1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/*
2f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet * Copyright 2010-2014, The Android Open Source Project
3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License.
6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at
7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *     http://www.apache.org/licenses/LICENSE-2.0
9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software
11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and
14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License.
15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */
16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang
176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_reflection.h"
18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
19e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <sys/stat.h>
20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
21462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include <cstdarg>
229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include <cctype>
23e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
24e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <algorithm>
25d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines#include <sstream>
26e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <string>
27e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <utility>
28462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
296315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/ADT/APFloat.h"
3089273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang#include "llvm/ADT/StringExtras.h"
316315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
328d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael#include "os_sep.h"
336315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h"
346315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_var.h"
35593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "slang_rs_export_foreach.h"
366315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_func.h"
377682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala#include "slang_rs_export_reduce.h"
386315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_reflect_utils.h"
39d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross#include "slang_rs_reflection_state.h"
404cc499d6e5ec602309501873449c938af61170b2Stephen Hines#include "slang_version.h"
416315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_SCRIPT_CLASS_NAME_PREFIX "ScriptC_"
439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#define RS_SCRIPT_CLASS_SUPER_CLASS_NAME "ScriptC"
44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
452ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_TYPE_CLASS_SUPER_CLASS_NAME ".Script.FieldBase"
46462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
472ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_TYPE_ITEM_CLASS_NAME "Item"
48462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
493a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray#define RS_TYPE_ITEM_SIZEOF_LEGACY "Item.sizeof"
503a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray#define RS_TYPE_ITEM_SIZEOF_CURRENT "mElement.getBytesSize()"
513a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray
522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_TYPE_ITEM_BUFFER_NAME "mItemArray"
532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_TYPE_ITEM_BUFFER_PACKER_NAME "mIOBuffer"
542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_TYPE_ELEMENT_REF_NAME "mElementCache"
55462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_EXPORT_VAR_INDEX_PREFIX "mExportVarIdx_"
572ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_EXPORT_VAR_PREFIX "mExportVar_"
582ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_EXPORT_VAR_ELEM_PREFIX "mExportVarElem_"
592ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_EXPORT_VAR_DIM_PREFIX "mExportVarDim_"
602ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_EXPORT_VAR_CONST_PREFIX "const_"
61462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
622ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_ELEM_PREFIX "__"
63a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines
642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_FP_PREFIX "__rs_fp_"
651f6c331d622ac645ab68a016aa4c577998547373Stephen Hines
662ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_RESOURCE_NAME "__rs_resource_name"
67d2936939ec10879e25746322db60071f79f28c1bStephen Hines
682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_EXPORT_FUNC_INDEX_PREFIX "mExportFuncIdx_"
692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_EXPORT_FOREACH_INDEX_PREFIX "mExportForEachIdx_"
707682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala#define RS_EXPORT_REDUCE_INDEX_PREFIX "mExportReduceIdx_"
71462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_EXPORT_VAR_ALLOCATION_PREFIX "mAlloction_"
739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#define RS_EXPORT_VAR_DATA_STORAGE_PREFIX "mData_"
74462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
757682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala#define SAVED_RS_REFERENCE "mRSLocal"
767682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
77e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
78462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
79d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Grossstatic void genCheck64BitInternal(const RSContext *Context, ReflectionState *State,
80d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                  GeneratedFile &Out, bool Parens);
81d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
82c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouilletclass RSReflectionJavaElementBuilder {
83c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouilletpublic:
84c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  RSReflectionJavaElementBuilder(const char *ElementBuilderName,
85c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                                 const RSExportRecordType *ERT,
86c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                                 const char *RenderScriptVar,
87c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                                 GeneratedFile *Out, const RSContext *RSContext,
88d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                 RSReflectionJava *Reflection,
89d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                 ReflectionState *RState);
90c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  void generate();
91c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
92c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouilletprivate:
93c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  void genAddElement(const RSExportType *ET, const std::string &VarName,
94c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                     unsigned ArraySize);
95c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  void genAddStatementStart();
96d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  void genAddStatementEnd(const std::string &VarName, unsigned ArraySize,
97d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                          unsigned Which = RSReflectionJava::FieldIndex | RSReflectionJava::Field32Index);
98d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  void genAddPadding(int PaddingSize, unsigned Which);  // Which: See RSReflectionJava::incFieldIndex()
99d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  void genAddPadding(int PaddingSize, ReflectionState::Val32 Field32PaddingSize);
100c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  // TODO Will remove later due to field name information is not necessary for
101c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  // C-reflect-to-Java
102c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  std::string createPaddingField() {
103c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    return mPaddingPrefix + llvm::itostr(mPaddingFieldIndex++);
104c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  }
105c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
106d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  void genCheck64Bit(bool Parens) {
107d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    genCheck64BitInternal(mRSContext, mState, *mOut, Parens);
108d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  }
109d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
110c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  const char *mElementBuilderName;
111c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  const RSExportRecordType *mERT;
112c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  const char *mRenderScriptVar;
113c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  GeneratedFile *mOut;
114c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  std::string mPaddingPrefix;
115c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  int mPaddingFieldIndex;
116c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  const RSContext *mRSContext;
117c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  RSReflectionJava *mReflection;
118d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  ReflectionState *mState;
119c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet};
120c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
121d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Grossenum MatrixLanguage { ML_Java, ML_Script };
122d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Grossstatic const char *GetMatrixTypeName(const RSExportMatrixType *EMT, MatrixLanguage lang) {
123d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  static const char *MatrixTypeJavaNameMap[3][2] = {/* 2x2 */ { "Matrix2f", "rs_matrix2x2" },
124d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                                    /* 3x3 */ { "Matrix3f", "rs_matrix3x3" },
125d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                                    /* 4x4 */ { "Matrix4f", "rs_matrix4x4" }
12692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang  };
12792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang  unsigned Dim = EMT->getDim();
12892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
1292ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  if ((Dim - 2) < (sizeof(MatrixTypeJavaNameMap) / sizeof(const char *)))
130d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    return MatrixTypeJavaNameMap[EMT->getDim() - 2][lang];
13192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
1326e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert(false && "GetMatrixTypeName : Unsupported matrix dimension");
1335abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  return nullptr;
13492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang}
13592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
1366e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hinesstatic const char *GetVectorAccessor(unsigned Index) {
1372ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  static const char *VectorAccessorMap[] = {/* 0 */ "x",
1382ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                            /* 1 */ "y",
1392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                            /* 2 */ "z",
1402ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                            /* 3 */ "w",
1419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  };
142324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao
1432ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  slangAssert((Index < (sizeof(VectorAccessorMap) / sizeof(const char *))) &&
1446e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines              "Out-of-bound index to access vector member");
145324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao
1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return VectorAccessorMap[Index];
147324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao}
148324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao
1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaostatic const char *GetPackerAPIName(const RSExportPrimitiveType *EPT) {
1506315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  static const char *PrimitiveTypePackerAPINameMap[] = {
1512a7ec01e812624ff7685d7de5528e8fc1a4acc9ePirama Arumuga Nainar      "addI16",     // DataTypeFloat16
1522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addF32",     // DataTypeFloat32
1532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addF64",     // DataTypeFloat64
1542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addI8",      // DataTypeSigned8
1552ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addI16",     // DataTypeSigned16
1562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addI32",     // DataTypeSigned32
1572ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addI64",     // DataTypeSigned64
1582ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addU8",      // DataTypeUnsigned8
1592ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addU16",     // DataTypeUnsigned16
1602ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addU32",     // DataTypeUnsigned32
1612ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addU64",     // DataTypeUnsigned64
1622ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addBoolean", // DataTypeBoolean
1632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addU16",     // DataTypeUnsigned565
1642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addU16",     // DataTypeUnsigned5551
1652ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addU16",     // DataTypeUnsigned4444
1662ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addMatrix",  // DataTypeRSMatrix2x2
1672ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addMatrix",  // DataTypeRSMatrix3x3
1682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addMatrix",  // DataTypeRSMatrix4x4
1692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSElement
1702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSType
1712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSAllocation
1722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSSampler
1732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSScript
1742ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSMesh
1752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSPath
1762ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSProgramFragment
1772ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSProgramVertex
1782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSProgramRaster
1792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSProgramStore
1802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSFont
1819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  };
1829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  unsigned TypeId = EPT->getType();
1839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  if (TypeId < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char *)))
1852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return PrimitiveTypePackerAPINameMap[EPT->getType()];
1869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1876e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert(false && "GetPackerAPIName : Unknown primitive data type");
1885abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  return nullptr;
189462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
190462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
191277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Grossnamespace {
192277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1931c6bf88e098c767c3cd445f2c2514f0598d91501David Grossstd::string GetReduceResultTypeName(const RSExportType *ET) {
194277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  switch (ET->getClass()) {
195277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    case RSExportType::ExportClassConstantArray: {
196277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      const RSExportConstantArrayType *const CAT = static_cast<const RSExportConstantArrayType *>(ET);
197277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      return "resultArray" + std::to_string(CAT->getNumElement()) + "_" +
19847cf31e869c1b6f149ac619f82939b9a8cab1180David Gross          RSReflectionJava::GetTypeName(
19947cf31e869c1b6f149ac619f82939b9a8cab1180David Gross              CAT->getElementType(),
20047cf31e869c1b6f149ac619f82939b9a8cab1180David Gross              (RSReflectionJava::TypeNameDefault & ~RSReflectionJava::TypeNameWithRecordElementName) |
20147cf31e869c1b6f149ac619f82939b9a8cab1180David Gross              RSReflectionJava::TypeNameC);
202277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
203277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    case RSExportType::ExportClassRecord:
20447cf31e869c1b6f149ac619f82939b9a8cab1180David Gross      return "resultStruct_" +
20547cf31e869c1b6f149ac619f82939b9a8cab1180David Gross          RSReflectionJava::GetTypeName(
20647cf31e869c1b6f149ac619f82939b9a8cab1180David Gross              ET,
20747cf31e869c1b6f149ac619f82939b9a8cab1180David Gross              (RSReflectionJava::TypeNameDefault & ~RSReflectionJava::TypeNameWithRecordElementName) |
20847cf31e869c1b6f149ac619f82939b9a8cab1180David Gross              RSReflectionJava::TypeNameC);
209277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    default:
21047cf31e869c1b6f149ac619f82939b9a8cab1180David Gross      return "result_" +
21147cf31e869c1b6f149ac619f82939b9a8cab1180David Gross          RSReflectionJava::GetTypeName(ET, RSReflectionJava::TypeNameDefault | RSReflectionJava::TypeNameC);
212277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
213277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
214277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
2151c6bf88e098c767c3cd445f2c2514f0598d91501David Grossstd::string GetReduceResultTypeName(const RSExportReduce *ER) {
2161c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  return GetReduceResultTypeName(ER->getResultType());
217277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
218277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
219277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross} // end anonymous namespace
220277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
221cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liaostatic const char *GetTypeNullValue(const RSExportType *ET) {
222cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao  switch (ET->getClass()) {
2232ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive: {
2242ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportPrimitiveType *EPT =
2252ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportPrimitiveType *>(ET);
2262ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (EPT->isRSObjectType())
227cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao      return "null";
2282ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    else if (EPT->getType() == DataTypeBoolean)
2292ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      return "false";
2302ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    else
2312ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      return "0";
2322ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
2332ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
2342ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPointer:
2352ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector:
2362ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassMatrix:
2372ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray:
2382ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
2392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return "null";
2402ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
2412ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
2422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default: { slangAssert(false && "Unknown class of type"); }
243cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao  }
244cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao  return "";
245cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao}
246cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao
24747aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hinesstatic std::string GetBuiltinElementConstruct(const RSExportType *ET) {
2482e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang  if (ET->getClass() == RSExportType::ExportClassPrimitive) {
249a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines    return std::string("Element.") + ET->getElementName();
2509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  } else if (ET->getClass() == RSExportType::ExportClassVector) {
2512ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportVectorType *EVT = static_cast<const RSExportVectorType *>(ET);
252cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet    if (EVT->getType() == DataTypeFloat32) {
253c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      if (EVT->getNumElement() == 2) {
2542b8fb64be3047df940a219872b331eb11de2758dStephen Hines        return "Element.F32_2";
255c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      } else if (EVT->getNumElement() == 3) {
2562b8fb64be3047df940a219872b331eb11de2758dStephen Hines        return "Element.F32_3";
257c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      } else if (EVT->getNumElement() == 4) {
2582b8fb64be3047df940a219872b331eb11de2758dStephen Hines        return "Element.F32_4";
259c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      } else {
260c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        slangAssert(false && "Vectors should be size 2, 3, 4");
261c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      }
262cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet    } else if (EVT->getType() == DataTypeUnsigned8) {
2632b8fb64be3047df940a219872b331eb11de2758dStephen Hines      if (EVT->getNumElement() == 4)
2642b8fb64be3047df940a219872b331eb11de2758dStephen Hines        return "Element.U8_4";
2659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
26692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang  } else if (ET->getClass() == RSExportType::ExportClassMatrix) {
26792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang    const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType *>(ET);
26892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang    switch (EMT->getDim()) {
2692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case 2:
2702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      return "Element.MATRIX_2X2";
2712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case 3:
2722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      return "Element.MATRIX_3X3";
2732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case 4:
2742ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      return "Element.MATRIX_4X4";
2752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    default:
2762ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      slangAssert(false && "Unsupported dimension of matrix");
27792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang    }
2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
27947aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines  // RSExportType::ExportClassPointer can't be generated in a struct.
280462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
28147aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines  return "";
28248b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines}
28348b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
2847682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// If FromIntegerType == DestIntegerType, then Value is returned.
2857682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// Otherwise, return a Java expression that zero-extends the value
2867682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// Value, assumed to be of type FromIntegerType, to the integer type
2877682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// DestIntegerType.
2887682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala//
2897682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// Intended operations:
2907682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala//  byte  -> {byte,int,short,long}
2917682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala//  short -> {short,int,long}
2927682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala//  int   -> {int,long}
2937682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala//  long  -> long
2947682b663581dd8f67b422f6f2f31692ab2f870e3Matt Walastatic std::string ZeroExtendValue(const std::string &Value,
2957682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala                                   const std::string &FromIntegerType,
2967682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala                                   const std::string &DestIntegerType) {
2977682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala#ifndef __DISABLE_ASSERTS
2987682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  // Integer types arranged in increasing order by width
2997682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  const std::vector<std::string> ValidTypes{"byte", "short", "int", "long"};
3007682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  auto FromTypeLoc = std::find(ValidTypes.begin(), ValidTypes.end(), FromIntegerType);
3017682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  auto DestTypeLoc = std::find(ValidTypes.begin(), ValidTypes.end(), DestIntegerType);
3027682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  // Check that both types are valid.
3037682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  slangAssert(FromTypeLoc != ValidTypes.end());
3047682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  slangAssert(DestTypeLoc != ValidTypes.end());
3057682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  // Check that DestIntegerType is at least as wide as FromIntegerType.
3067682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  slangAssert(FromTypeLoc - ValidTypes.begin() <= DestTypeLoc - ValidTypes.begin());
3077682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala#endif
3087682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
3097682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  if (FromIntegerType == DestIntegerType) {
3107682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    return Value;
3117682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  }
3127682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
3137682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  std::string Mask, MaskLiteralType;
3147682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  if (FromIntegerType == "byte") {
3157682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    Mask = "0xff";
3167682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    MaskLiteralType = "int";
3177682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  } else if (FromIntegerType == "short") {
3187682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    Mask = "0xffff";
3197682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    MaskLiteralType = "int";
3207682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  } else if (FromIntegerType == "int") {
3217682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    Mask = "0xffffffffL";
3227682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    MaskLiteralType = "long";
3237682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  } else {
3247682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    // long -> long casts should have already been handled.
3257682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    slangAssert(false && "Unknown integer type");
3267682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  }
3277682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
3287682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  // Cast the mask to the appropriate type.
3297682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  if (MaskLiteralType != DestIntegerType) {
3307682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    Mask = "(" + DestIntegerType + ") " + Mask;
3317682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  }
3327682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  return "((" + DestIntegerType + ") ((" + Value + ") & " + Mask + "))";
3337682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala}
3347682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
33547cf31e869c1b6f149ac619f82939b9a8cab1180David Grossstd::string RSReflectionJava::GetTypeName(const RSExportType *ET, unsigned Style) {
336d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  slangAssert((Style & (TypeNameC|TypeNamePseudoC)) != (TypeNameC|TypeNamePseudoC));
337d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  slangAssert(!(Style & TypeNamePseudoC) || (Style == TypeNamePseudoC));
338d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
339d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  const bool CLike = Style & (TypeNameC|TypeNamePseudoC);
340d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
34147cf31e869c1b6f149ac619f82939b9a8cab1180David Gross  switch (ET->getClass()) {
34247cf31e869c1b6f149ac619f82939b9a8cab1180David Gross  case RSExportType::ExportClassPrimitive: {
34347cf31e869c1b6f149ac619f82939b9a8cab1180David Gross    const auto ReflectionType =
34447cf31e869c1b6f149ac619f82939b9a8cab1180David Gross        RSExportPrimitiveType::getRSReflectionType(static_cast<const RSExportPrimitiveType *>(ET));
345d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    return (CLike ? ReflectionType->s_name : ReflectionType->java_name);
34647cf31e869c1b6f149ac619f82939b9a8cab1180David Gross  }
34747cf31e869c1b6f149ac619f82939b9a8cab1180David Gross  case RSExportType::ExportClassPointer: {
34847cf31e869c1b6f149ac619f82939b9a8cab1180David Gross    slangAssert(!(Style & TypeNameC) &&
34947cf31e869c1b6f149ac619f82939b9a8cab1180David Gross                "No need to support C type names for pointer types yet");
35047cf31e869c1b6f149ac619f82939b9a8cab1180David Gross    const RSExportType *PointeeType =
35147cf31e869c1b6f149ac619f82939b9a8cab1180David Gross        static_cast<const RSExportPointerType *>(ET)->getPointeeType();
35247cf31e869c1b6f149ac619f82939b9a8cab1180David Gross
353d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (Style & TypeNamePseudoC)
354d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      return GetTypeName(PointeeType, Style) + "*";
355d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    else if (PointeeType->getClass() != RSExportType::ExportClassRecord)
35647cf31e869c1b6f149ac619f82939b9a8cab1180David Gross      return "Allocation";
35747cf31e869c1b6f149ac619f82939b9a8cab1180David Gross    else
35847cf31e869c1b6f149ac619f82939b9a8cab1180David Gross      return PointeeType->getElementName();
35947cf31e869c1b6f149ac619f82939b9a8cab1180David Gross  }
36047cf31e869c1b6f149ac619f82939b9a8cab1180David Gross  case RSExportType::ExportClassVector: {
36147cf31e869c1b6f149ac619f82939b9a8cab1180David Gross    const RSExportVectorType *EVT = static_cast<const RSExportVectorType *>(ET);
36247cf31e869c1b6f149ac619f82939b9a8cab1180David Gross    const auto ReflectionType = EVT->getRSReflectionType(EVT);
36347cf31e869c1b6f149ac619f82939b9a8cab1180David Gross    std::stringstream VecName;
364d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    VecName << (CLike ? ReflectionType->s_name : ReflectionType->rs_java_vector_prefix)
36547cf31e869c1b6f149ac619f82939b9a8cab1180David Gross            << EVT->getNumElement();
36647cf31e869c1b6f149ac619f82939b9a8cab1180David Gross    return VecName.str();
36747cf31e869c1b6f149ac619f82939b9a8cab1180David Gross  }
36847cf31e869c1b6f149ac619f82939b9a8cab1180David Gross  case RSExportType::ExportClassMatrix: {
369d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    return GetMatrixTypeName(static_cast<const RSExportMatrixType *>(ET), CLike ? ML_Script : ML_Java);
37047cf31e869c1b6f149ac619f82939b9a8cab1180David Gross  }
37147cf31e869c1b6f149ac619f82939b9a8cab1180David Gross  case RSExportType::ExportClassConstantArray: {
37247cf31e869c1b6f149ac619f82939b9a8cab1180David Gross    const RSExportConstantArrayType *CAT =
37347cf31e869c1b6f149ac619f82939b9a8cab1180David Gross        static_cast<const RSExportConstantArrayType *>(ET);
37447cf31e869c1b6f149ac619f82939b9a8cab1180David Gross    std::string ElementTypeName = GetTypeName(CAT->getElementType(), Style);
375d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (Style & TypeNamePseudoC) {
376d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      std::stringstream ArrayName;
377d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      ArrayName << ElementTypeName << '[' << CAT->getNumElement() << ']';
378d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      return ArrayName.str();
379d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    }
380d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    else if (Style & TypeNameWithConstantArrayBrackets) {
38147cf31e869c1b6f149ac619f82939b9a8cab1180David Gross      slangAssert(!(Style & TypeNameC) &&
38247cf31e869c1b6f149ac619f82939b9a8cab1180David Gross                  "No need to support C type names for array types with brackets yet");
38347cf31e869c1b6f149ac619f82939b9a8cab1180David Gross      ElementTypeName.append("[]");
38447cf31e869c1b6f149ac619f82939b9a8cab1180David Gross    }
38547cf31e869c1b6f149ac619f82939b9a8cab1180David Gross    return ElementTypeName;
38647cf31e869c1b6f149ac619f82939b9a8cab1180David Gross  }
38747cf31e869c1b6f149ac619f82939b9a8cab1180David Gross  case RSExportType::ExportClassRecord: {
38847cf31e869c1b6f149ac619f82939b9a8cab1180David Gross    slangAssert(!(Style & TypeNameC) &&
38947cf31e869c1b6f149ac619f82939b9a8cab1180David Gross                "No need to support C type names for record types yet");
390d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (Style & TypeNamePseudoC)
391d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      return "struct " + ET->getName();
392d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    else if (Style & TypeNameWithRecordElementName)
39347cf31e869c1b6f149ac619f82939b9a8cab1180David Gross      return ET->getElementName() + "." RS_TYPE_ITEM_CLASS_NAME;
39447cf31e869c1b6f149ac619f82939b9a8cab1180David Gross    else
39547cf31e869c1b6f149ac619f82939b9a8cab1180David Gross      return ET->getName();
39647cf31e869c1b6f149ac619f82939b9a8cab1180David Gross  }
39747cf31e869c1b6f149ac619f82939b9a8cab1180David Gross  default: { slangAssert(false && "Unknown class of type"); }
39847cf31e869c1b6f149ac619f82939b9a8cab1180David Gross  }
39947cf31e869c1b6f149ac619f82939b9a8cab1180David Gross
40047cf31e869c1b6f149ac619f82939b9a8cab1180David Gross  return "";
40147cf31e869c1b6f149ac619f82939b9a8cab1180David Gross}
40247cf31e869c1b6f149ac619f82939b9a8cab1180David Gross
403d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Grossvoid RSReflectionJava::genConditionalVal(const std::string &Prefix, bool Parens,
404d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                         size_t Val, ReflectionState::Val32 Val32) {
405d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (Prefix.empty() || (Val != 0) || (Val32.first && (Val32.second != 0 ))) {
406d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mOut << Prefix;
407d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
408d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (!Val32.first || (Val == Val32.second)) {
409d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      // Either we're ignoring the 32-bit case, or 32-bit and 64-bit
410d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      // values are the same.
411d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      mOut << Val;
412d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    } else {
413d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      // We cannot ignore the 32-bit case, and 32-bit and 64-bit
414d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      // values differ.
415d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      if (Parens)
416d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        mOut << '(';
417d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      genCheck64Bit(true);
418d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      mOut << " ? " << Val << " : " << Val32.second;
419d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      if (Parens)
420d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        mOut << ')';
421d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    }
422d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  }
423d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross}
424d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
425d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Grossstatic void genCheck64BitInternal(const RSContext *Context, ReflectionState *State,
426d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                  GeneratedFile &Out, bool Parens) {
427d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  State->setOutputClassDivergent();
428d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (Context->isCompatLib()) {
429d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (Parens)
430d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      Out << '(';
431d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    Out << "RenderScript.getPointerSize() == 8";
432d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (Parens)
433d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      Out << ')';
434d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  }
435d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  else
436d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    Out << "sIs64Bit";
437d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross}
438d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
439d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Grossvoid RSReflectionJava::genCheck64Bit(bool Parens) {
440d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  genCheck64BitInternal(mRSContext, mState, mOut, Parens);
441d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross}
442d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
443d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Grossvoid RSReflectionJava::genCompute64Bit() {
444d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (mRSContext->isCompatLib()) {
445d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    // We can rely on RenderScript class in lockstep with llvm-rs-cc
446d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    // and hence in lockstep with the generated code, so we don't need
447d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    // any complicated logic to determine pointer size.
448d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    return;
449d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  }
450d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
451d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // Note that Android L is the first release to support 64-bit
452d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // targets.  When RenderScript is compiled with "-target-api $v"
453d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // with "$v < 21" (L is API level 21), we only compile for 32-bit,
454d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // and we reflect during that compile, so there are no divergent
455d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // structs, and we will not get here.
456d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
457d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  slangAssert(mRSContext->getTargetAPI() >= SLANG_L_TARGET_API);
458d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
459d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.indent() << "private static boolean sIs64Bit;\n\n";
460d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.indent() << "static";
461d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.startBlock();
462d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.indent() << "if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)";
463d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.startBlock();
464d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.indent() << "sIs64Bit = Process.is64Bit();\n";
465d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.endBlock();
466d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.indent() << "else";
467d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.startBlock();
468d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.indent() << "try";
469d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.startBlock();
470d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.indent() << "Field f = RenderScript.class.getDeclaredField(\"sPointerSize\");\n";
471d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.indent() << "f.setAccessible(true);\n";
472d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.indent() << "sIs64Bit = (f.getInt(null) == 8);\n";
473d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.endBlock();
474d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
475d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // If reflection fails, assume we're on a 32-bit-only device
476d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // (64-bit-only is not allowed).  This should only happen if the
477d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // device is L-or-later but has been customized in some way so that
478d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // the field "sPointerSize" -- introduced in L -- is not present.
479d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  //
480d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // Alternatively, we could treat this as 64-bit (reverting to the
481d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // behavior prior to the fix for http://b/32780232) or we could
482d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // decide we have no idea what's going on and throw an exception.
483d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.indent() << "catch (Throwable e)";
484d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.startBlock();
485d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.indent() << "sIs64Bit = false;\n";
486d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.endBlock();
487d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
488d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.endBlock();
489d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut.endBlock();
490d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross}
491d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
4929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/********************** Methods to generate script class **********************/
49359f22c376b2c1cd109735280689224fadfe40b42Jean-Luc BrouilletRSReflectionJava::RSReflectionJava(const RSContext *Context,
49459f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                                   std::vector<std::string> *GeneratedFileNames,
49559f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                                   const std::string &OutputBaseDirectory,
49659f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                                   const std::string &RSSourceFileName,
49759f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                                   const std::string &BitCodeFileName,
498d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                   bool EmbedBitcodeInJava,
499d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                   ReflectionState *RState)
500d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    : mRSContext(Context), mState(RState), mCollecting(RState->isCollecting()),
501d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      mPackageName(Context->getReflectJavaPackageName()),
50259f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet      mRSPackageName(Context->getRSPackageName()),
50359f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet      mOutputBaseDirectory(OutputBaseDirectory),
50459f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet      mRSSourceFileName(RSSourceFileName), mBitCodeFileName(BitCodeFileName),
50559f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet      mResourceId(RSSlangReflectUtils::JavaClassNameFromRSFileName(
50659f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet          mBitCodeFileName.c_str())),
50759f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet      mScriptClassName(RS_SCRIPT_CLASS_NAME_PREFIX +
50859f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                       RSSlangReflectUtils::JavaClassNameFromRSFileName(
50959f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                           mRSSourceFileName.c_str())),
510c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      mEmbedBitcodeInJava(EmbedBitcodeInJava), mNextExportVarSlot(0),
5117682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala      mNextExportFuncSlot(0), mNextExportForEachSlot(0),
5121c6bf88e098c767c3cd445f2c2514f0598d91501David Gross      mNextExportReduceSlot(0), mLastError(""),
513d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mGeneratedFileNames(GeneratedFileNames), mFieldIndex(0), mField32Index(0) {
51459f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet  slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames");
51559f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet  slangAssert(!mPackageName.empty() && mPackageName != "-");
51659f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet
51759f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet  mOutputDirectory = RSSlangReflectUtils::ComputePackagedPath(
51859f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                         OutputBaseDirectory.c_str(), mPackageName.c_str()) +
51959f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                     OS_PATH_SEPARATOR_STR;
5203a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray
5213a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray  // mElement.getBytesSize only exists on JB+
5223a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray  if (mRSContext->getTargetAPI() >= SLANG_JB_TARGET_API) {
5233a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray      mItemSizeof = RS_TYPE_ITEM_SIZEOF_CURRENT;
5243a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray  } else {
5253a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray      mItemSizeof = RS_TYPE_ITEM_SIZEOF_LEGACY;
5263a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray  }
527d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
528d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mState->nextFile(mRSContext, mPackageName, mRSSourceFileName);
52959f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet}
53059f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet
5312e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletbool RSReflectionJava::genScriptClass(const std::string &ClassName,
532602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                      std::string &ErrorMsg) {
533d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (!mCollecting) {
534d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (!startClass(AM_Public, false, ClassName, RS_SCRIPT_CLASS_SUPER_CLASS_NAME,
535d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                    ErrorMsg))
536d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      return false;
5379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
538d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mState->beginOutputClass();
539d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    genScriptClassConstructor();
540d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  }
5419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
5427682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  // Reflect exported variables
543d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mState->beginVariables(mRSContext->export_vars_size());
5447682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  for (auto I = mRSContext->export_vars_begin(),
5457682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala            E = mRSContext->export_vars_end();
5462ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++)
5472e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genExportVariable(*I);
548d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mState->endVariables();
5499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
5507682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  // Reflect exported forEach functions (only available on ICS+)
5514cc499d6e5ec602309501873449c938af61170b2Stephen Hines  if (mRSContext->getTargetAPI() >= SLANG_ICS_TARGET_API) {
552d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mState->beginForEaches(mRSContext->getNumAssignedForEachOrdinals());
5537682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    for (auto I = mRSContext->export_foreach_begin(),
5547682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala              E = mRSContext->export_foreach_end();
5557682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala         I != E; I++) {
5562e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genExportForEach(*I);
5577682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    }
558d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mState->endForEaches();
5594a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines  }
560593a894650e81be54173106ec266f0311cebebd3Stephen Hines
561d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // Reflect exported reduce functions
562d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (!mCollecting) {
563d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    for (const RSExportType *ResultType : mRSContext->getReduceResultTypes(
564d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross             // FilterIn
565d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross             exportableReduce,
566277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
567d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross             // Compare
568d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross             [](const RSExportType *A, const RSExportType *B)
569d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross             { return GetReduceResultTypeName(A) < GetReduceResultTypeName(B); }))
570d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      genExportReduceResultType(ResultType);
571d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  }
572d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mState->beginReduces(mRSContext->export_reduce_size());
5731c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  for (auto I = mRSContext->export_reduce_begin(),
5741c6bf88e098c767c3cd445f2c2514f0598d91501David Gross            E = mRSContext->export_reduce_end();
575277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross       I != E; ++I)
5761c6bf88e098c767c3cd445f2c2514f0598d91501David Gross    genExportReduce(*I);
577d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mState->endReduces();
578277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
5797682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  // Reflect exported functions (invokable)
580d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mState->beginInvokables(mRSContext->export_funcs_size());
5817682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  for (auto I = mRSContext->export_funcs_begin(),
5827682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala            E = mRSContext->export_funcs_end();
5837682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala       I != E; ++I)
5842e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genExportFunction(*I);
585d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mState->endInvokables();
5869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
587d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (!mCollecting) {
588d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (mState->endOutputClass())
589d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      genCompute64Bit();
590d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
591d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    endClass();
592d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
593d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mGeneratedFileNames->push_back(mScriptClassName);
594d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  }
5959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
5969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
5979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
598462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
5992e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genScriptClassConstructor() {
6004c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines  std::string className(RSSlangReflectUtils::JavaBitcodeClassNameFromRSFileName(
60159f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet      mRSSourceFileName.c_str()));
602d2936939ec10879e25746322db60071f79f28c1bStephen Hines  // Provide a simple way to reference this object.
603f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "private static final String " RS_RESOURCE_NAME " = \""
604f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << getResourceId() << "\";\n";
605d2936939ec10879e25746322db60071f79f28c1bStephen Hines
606d2936939ec10879e25746322db60071f79f28c1bStephen Hines  // Generate a simple constructor with only a single parameter (the rest
607d2936939ec10879e25746322db60071f79f28c1bStephen Hines  // can be inferred from information we already have).
608f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "// Constructor\n";
6095abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  startFunction(AM_Public, false, nullptr, getClassName(), 1, "RenderScript",
6102e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "rs");
61144d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines
6127682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  const bool haveReduceExportables =
6131c6bf88e098c767c3cd445f2c2514f0598d91501David Gross    mRSContext->export_reduce_begin() != mRSContext->export_reduce_end();
6147682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
6152e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  if (getEmbedBitcodeInJava()) {
6164c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines    // Call new single argument Java-only constructor
617f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "super(rs,\n";
618f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "      " << RS_RESOURCE_NAME ",\n";
619f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "      " << className << ".getBitCode32(),\n";
6209ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    mOut.indent() << "      " << className << ".getBitCode64());\n";
6214c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines  } else {
6224c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines    // Call alternate constructor with required parameters.
6234c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines    // Look up the proper raw bitcode resource id via the context.
624f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "this(rs,\n";
625f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "     rs.getApplicationContext().getResources(),\n";
626f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "     rs.getApplicationContext().getResources()."
627f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                     "getIdentifier(\n";
628f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "         " RS_RESOURCE_NAME ", \"raw\",\n";
629f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent()
630f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        << "         rs.getApplicationContext().getPackageName()));\n";
6312e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    endFunction();
6324c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines
6334c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines    // Alternate constructor (legacy) with 3 original parameters.
6345abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    startFunction(AM_Public, false, nullptr, getClassName(), 3, "RenderScript",
6352e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  "rs", "Resources", "resources", "int", "id");
6364c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines    // Call constructor of super class
637f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "super(rs, resources, id);\n";
63844d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines  }
639b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams
640d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // If an exported variable has initial value, reflect it.
641d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // Keep this in sync with initialization handling in ReflectionState::declareVariable().
642b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams
6437682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  for (auto I = mRSContext->export_vars_begin(),
6447682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala            E = mRSContext->export_vars_end();
6452ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++) {
646b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams    const RSExportVar *EV = *I;
647d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines    if (!EV->getInit().isUninit()) {
6482e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genInitExportVariable(EV->getType(), EV->getName(), EV->getInit());
649d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines    } else if (EV->getArraySize()) {
650d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      // Always create an initial zero-init array object.
651f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = new "
652277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                    << GetTypeName(EV->getType(), TypeNameDefault & ~TypeNameWithConstantArrayBrackets) << "["
653f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << EV->getArraySize() << "];\n";
654d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      size_t NumInits = EV->getNumInits();
655d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      const RSExportConstantArrayType *ECAT =
6562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet          static_cast<const RSExportConstantArrayType *>(EV->getType());
657d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      const RSExportType *ET = ECAT->getElementType();
658d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      for (size_t i = 0; i < NumInits; i++) {
659d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        std::stringstream Name;
660d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        Name << EV->getName() << "[" << i << "]";
6612e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        genInitExportVariable(ET, Name.str(), EV->getInitArray(i));
662d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      }
663d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines    }
664a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines    if (mRSContext->getTargetAPI() >= SLANG_JB_TARGET_API) {
6652e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genTypeInstance(EV->getType());
666a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines    }
6672e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genFieldPackerInstance(EV->getType());
668b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams  }
669b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams
6707682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  if (haveReduceExportables) {
6717682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    mOut.indent() << SAVED_RS_REFERENCE << " = rs;\n";
6727682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  }
6737682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
6747682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  // Reflect argument / return types in kernels
6757682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
6767682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  for (auto I = mRSContext->export_foreach_begin(),
6777682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala            E = mRSContext->export_foreach_end();
6782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++) {
67948b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    const RSExportForEach *EF = *I;
68048b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
681c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    const RSExportForEach::InTypeVec &InTypes = EF->getInTypes();
682c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    for (RSExportForEach::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
683c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes         BI != EI; BI++) {
6845abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes      if (*BI != nullptr) {
685c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        genTypeInstanceFromPointer(*BI);
686c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      }
68748b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    }
688c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
68948b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    const RSExportType *OET = EF->getOutType();
69048b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    if (OET) {
6912e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genTypeInstanceFromPointer(OET);
69248b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    }
69348b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  }
69448b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
6957682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  for (auto I = mRSContext->export_reduce_begin(),
6967682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala            E = mRSContext->export_reduce_end();
6977682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala       I != E; I++) {
6987682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    const RSExportReduce *ER = *I;
699277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
700277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const RSExportType *RT = ER->getResultType();
701277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    slangAssert(RT != nullptr);
7021c6bf88e098c767c3cd445f2c2514f0598d91501David Gross    if (!exportableReduce(RT))
703277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      continue;
704277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
705277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    genTypeInstance(RT);
706277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
7071c6bf88e098c767c3cd445f2c2514f0598d91501David Gross    const RSExportReduce::InTypeVec &InTypes = ER->getAccumulatorInTypes();
7081c6bf88e098c767c3cd445f2c2514f0598d91501David Gross    for (RSExportReduce::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
709277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross         BI != EI; BI++) {
710277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      slangAssert(*BI != nullptr);
711277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      genTypeInstance(*BI);
712277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
713277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
714277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
7152e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
716b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams
7172e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  for (std::set<std::string>::iterator I = mTypesToCheck.begin(),
7182e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                       E = mTypesToCheck.end();
7192ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++) {
720f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "private Element " RS_ELEM_PREFIX << *I << ";\n";
72148b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  }
72248b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
7232e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  for (std::set<std::string>::iterator I = mFieldPackerTypes.begin(),
7242e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                       E = mFieldPackerTypes.end();
7252ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++) {
726f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "private FieldPacker " RS_FP_PREFIX << *I << ";\n";
7271f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  }
7287682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
7297682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  if (haveReduceExportables) {
7307682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    // We save a private copy of rs in order to create temporary
7317682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    // allocations in the reduce_* entry points.
7327682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    mOut.indent() << "private RenderScript " << SAVED_RS_REFERENCE << ";\n";
7337682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  }
7349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
735462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
7362e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genInitBoolExportVariable(const std::string &VarName,
737602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                                 const clang::APValue &Val) {
7386e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert(!Val.isUninit() && "Not a valid initializer");
7392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  slangAssert((Val.getKind() == clang::APValue::Int) &&
7402ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet              "Bool type has wrong initial APValue");
741462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
742f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
743462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
744f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << ((Val.getInt().getSExtValue() == 0) ? "false" : "true") << ";\n";
745462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
746462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
7472e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid
7482e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc BrouilletRSReflectionJava::genInitPrimitiveExportVariable(const std::string &VarName,
7492e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                                 const clang::APValue &Val) {
7505d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines  slangAssert(!Val.isUninit() && "Not a valid initializer");
7515d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines
752f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
753efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  genInitValue(Val, false);
754f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << ";\n";
75548bac230fe966771f3074975fc2426ffde519edfShih-wei Liao}
75648bac230fe966771f3074975fc2426ffde519edfShih-wei Liao
7572e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genInitExportVariable(const RSExportType *ET,
758602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                             const std::string &VarName,
759602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                             const clang::APValue &Val) {
7606e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert(!Val.isUninit() && "Not a valid initializer");
7619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
7629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  switch (ET->getClass()) {
7632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive: {
7642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportPrimitiveType *EPT =
7652ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportPrimitiveType *>(ET);
7662ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (EPT->getType() == DataTypeBoolean) {
7672e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genInitBoolExportVariable(VarName, Val);
7682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    } else {
7692e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genInitPrimitiveExportVariable(VarName, Val);
770324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao    }
7712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
7722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
7732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPointer: {
7742ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (!Val.isInt() || Val.getInt().getSExtValue() != 0)
7752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      std::cout << "Initializer which is non-NULL to pointer type variable "
7762ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                   "will be ignored\n";
7772ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
7782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
7792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector: {
7802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportVectorType *EVT = static_cast<const RSExportVectorType *>(ET);
7812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    switch (Val.getKind()) {
7822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Int:
7832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Float: {
7842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      for (unsigned i = 0; i < EVT->getNumElement(); i++) {
7852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        std::string Name = VarName + "." + GetVectorAccessor(i);
7862e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        genInitPrimitiveExportVariable(Name, Val);
7872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      }
7889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
7899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
7902ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Vector: {
7912ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      std::stringstream VecName;
7922ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      VecName << EVT->getRSReflectionType(EVT)->rs_java_vector_prefix
7932ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet              << EVT->getNumElement();
794f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new "
795f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << VecName.str() << "();\n";
7962ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
7972ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      unsigned NumElements = std::min(
7982ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet          static_cast<unsigned>(EVT->getNumElement()), Val.getVectorLength());
7992ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      for (unsigned i = 0; i < NumElements; i++) {
8002ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        const clang::APValue &ElementVal = Val.getVectorElt(i);
8012ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        std::string Name = VarName + "." + GetVectorAccessor(i);
8022e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        genInitPrimitiveExportVariable(Name, ElementVal);
8039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
8049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
805324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao    }
8062ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::MemberPointer:
8072ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Uninitialized:
8082ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::ComplexInt:
8092ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::ComplexFloat:
8102ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::LValue:
8112ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Array:
8122ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Struct:
8132ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Union:
8142ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::AddrLabelDiff: {
8152ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      slangAssert(false && "Unexpected type of value of initializer.");
8162ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
8172ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
8182ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
8192ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
8202ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  // TODO(zonr): Resolving initializer of a record (and matrix) type variable
8212ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  // is complex. It cannot obtain by just simply evaluating the initializer
8222ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  // expression.
8232ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassMatrix:
8242ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray:
8252ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
8269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#if 0
8279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      unsigned InitIndex = 0;
8286315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportRecordType *ERT =
8296315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr          static_cast<const RSExportRecordType*>(ET);
830462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
8316e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert((Val.getKind() == clang::APValue::Vector) &&
8326e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines          "Unexpected type of initializer for record type variable");
833462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
834f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName
835a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines                 << " = new " << ERT->getElementName()
8362968921e1cedf85360964c5a39e1ce36c66ecd09Jean-Luc Brouillet                 <<  "." RS_TYPE_ITEM_CLASS_NAME"();\n";
837462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
8389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
8399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao               E = ERT->fields_end();
8409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao           I != E;
8419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao           I++) {
8429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const RSExportRecordType::Field *F = *I;
8439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        std::string FieldName = VarName + "." + F->getName();
844462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
8459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (InitIndex > Val.getVectorLength())
8469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          break;
847462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
848f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        genInitPrimitiveExportVariable(FieldName,
8499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                       Val.getVectorElt(InitIndex++));
8509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
8519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#endif
8522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    slangAssert(false && "Unsupported initializer for record/matrix/constant "
8532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                         "array type variable currently");
8542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
8552ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
8562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default: { slangAssert(false && "Unknown class of type"); }
8579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
858462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
859462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
8602e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genExportVariable(const RSExportVar *EV) {
8619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const RSExportType *ET = EV->getType();
862462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
863d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  const ReflectionState::Val32
864d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      AllocSize32 = mState->declareVariable(EV);
865d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
866d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (mCollecting)
867d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    return;
868d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
869f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "private final static int " << RS_EXPORT_VAR_INDEX_PREFIX
870f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << EV->getName() << " = " << getNextExportVarSlot() << ";\n";
871462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
8729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  switch (ET->getClass()) {
8732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive: {
8742e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genPrimitiveTypeExportVariable(EV);
8752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
8762ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
8772ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPointer: {
8782e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genPointerTypeExportVariable(EV);
8792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
8802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
8812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector: {
8822e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genVectorTypeExportVariable(EV);
8832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
8842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
8852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassMatrix: {
8862e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genMatrixTypeExportVariable(EV);
8872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
8882ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
8892ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray: {
890d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    genConstantArrayTypeExportVariable(EV, AllocSize32);
8912ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
8922ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
8932ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
894d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    genRecordTypeExportVariable(EV, AllocSize32);
8952ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
8962ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
8972ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default: { slangAssert(false && "Unknown class of type"); }
8989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
899462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
900462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
901d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross// Keep this in sync with Invokable analysis in ReflectionState::declareInvokable().
9022e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genExportFunction(const RSExportFunc *EF) {
903d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mState->declareInvokable(EF);
904d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
905d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (!mCollecting) {
906d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mOut.indent() << "private final static int " << RS_EXPORT_FUNC_INDEX_PREFIX
907d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                  << EF->getName() << " = " << getNextExportFuncSlot() << ";\n";
908d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  }
9099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
9109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // invoke_*()
9112e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  ArgTy Args;
9129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
913d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (!mCollecting) {
914d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (EF->hasParam()) {
915d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      for (RSExportFunc::const_param_iterator I = EF->params_begin(),
916d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                              E = EF->params_end();
917d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross           I != E; I++) {
918d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        Args.push_back(
919d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross            std::make_pair(GetTypeName((*I)->getType()), (*I)->getName()));
920d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      }
9210da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang    }
9229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
923d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (mRSContext->getTargetAPI() >= SLANG_M_TARGET_API) {
924d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      startFunction(AM_Public, false, "Script.InvokeID",
925d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                    "getInvokeID_" + EF->getName(), 0);
926cec2a1d2e38ebd644c9f63e83bf5649f15df99d5Yang Ni
927d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      mOut.indent() << "return createInvokeID(" << RS_EXPORT_FUNC_INDEX_PREFIX
928d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                    << EF->getName() << ");\n";
929cec2a1d2e38ebd644c9f63e83bf5649f15df99d5Yang Ni
930d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      endFunction();
931d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    }
932cec2a1d2e38ebd644c9f63e83bf5649f15df99d5Yang Ni
933d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    startFunction(AM_Public, false, "void",
934d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                  "invoke_" + EF->getName(/*Mangle=*/false),
935d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                  // We are using un-mangled name since Java
936d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                  // supports method overloading.
937d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                  Args);
938d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  }
9399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
9409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!EF->hasParam()) {
941d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (!mCollecting)
942d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      mOut.indent() << "invoke(" << RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName()
943d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                    << ");\n";
9449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  } else {
9459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    const RSExportRecordType *ERT = EF->getParamPacketType();
946d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
947d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    // NOTE: This type isn't on the RSContext::export_types* list.
948d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mState->declareRecord(ERT, false);
949d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
9509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    std::string FieldPackerName = EF->getName() + "_fp";
9519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
952d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (genCreateFieldPacker(ERT, FieldPackerName.c_str(),
953d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                             mState->getRecord32(ERT).getRecordAllocSize()))
9545abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes      genPackVarOfType(ERT, nullptr, FieldPackerName.c_str());
9559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
956d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (!mCollecting)
957d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      mOut.indent() << "invoke(" << RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName()
958d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                    << ", " << FieldPackerName << ");\n";
9599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
9609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
961d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (!mCollecting)
962d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    endFunction();
9639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
964462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
965e2ead846c1d78a6e7108e521ffd15850bd9eed3cChih-Hung Hsiehvoid RSReflectionJava::genPairwiseDimCheck(const std::string &name0,
966e2ead846c1d78a6e7108e521ffd15850bd9eed3cChih-Hung Hsieh                                           const std::string &name1) {
967c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "// Verify dimensions\n";
968c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "t0 = " << name0 << ".getType();\n";
969c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "t1 = " << name1 << ".getType();\n";
970c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "if ((t0.getCount() != t1.getCount()) ||\n";
971c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "    (t0.getX() != t1.getX()) ||\n";
972c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "    (t0.getY() != t1.getY()) ||\n";
973c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "    (t0.getZ() != t1.getZ()) ||\n";
974c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "    (t0.hasFaces()   != t1.hasFaces()) ||\n";
975c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "    (t0.hasMipmaps() != t1.hasMipmaps())) {\n";
976c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "    throw new RSRuntimeException(\"Dimension mismatch "
977c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes                << "between parameters " << name0 << " and " << name1
978c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes                << "!\");\n";
979c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "}\n\n";
980c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes}
981c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
982277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Grossvoid RSReflectionJava::genNullArrayCheck(const std::string &ArrayName) {
9837682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  mOut.indent() << "// Verify that \"" << ArrayName << "\" is non-null.\n";
9847682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  mOut.indent() << "if (" << ArrayName << " == null) {\n";
9857682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  mOut.indent() << "    throw new RSIllegalArgumentException(\"Array \\\""
9867682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala                << ArrayName << "\\\" is null!\");\n";
9877682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  mOut.indent() << "}\n";
988277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
989277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
9907682b663581dd8f67b422f6f2f31692ab2f870e3Matt Walavoid RSReflectionJava::genVectorLengthCompatibilityCheck(const std::string &ArrayName,
9917682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala                                                         unsigned VecSize) {
9927682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  mOut.indent() << "// Verify that the array length is a multiple of the vector size.\n";
9937682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  mOut.indent() << "if (" << ArrayName << ".length % " << std::to_string(VecSize)
9947682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala                << " != 0) {\n";
9957682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  mOut.indent() << "    throw new RSIllegalArgumentException(\"Array \\\"" << ArrayName
9967682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala                << "\\\" is not a multiple of " << std::to_string(VecSize)
9977682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala                << " in length!\");\n";
9987682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  mOut.indent() << "}\n";
9997682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala}
10007682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
1001d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross// Keep this in sync with ForEach analysis in ReflectionState::beginForEach()
1002d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross// and other ReflectionState::*ForEach*() methods.
10032e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genExportForEach(const RSExportForEach *EF) {
1004c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  if (EF->isDummyRoot()) {
1005d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mState->declareForEachDummyRoot(EF);
1006d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
1007d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (!mCollecting) {
1008d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      // Skip reflection for dummy root() kernels. Note that we have to
1009d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      // advance the next slot number for ForEach, however.
1010d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      mOut.indent() << "//private final static int "
1011d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                    << RS_EXPORT_FOREACH_INDEX_PREFIX << EF->getName() << " = "
1012d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                    << getNextExportForEachSlot() << ";\n";
1013d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    }
1014d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
1015c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines    return;
1016c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  }
1017c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
1018d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (!mCollecting) {
1019d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mOut.indent() << "private final static int " << RS_EXPORT_FOREACH_INDEX_PREFIX
1020d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                  << EF->getName() << " = " << getNextExportForEachSlot()
1021d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                  << ";\n";
1022d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  }
1023593a894650e81be54173106ec266f0311cebebd3Stephen Hines
1024b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  // forEach_*()
10252e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  ArgTy Args;
1026fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross  bool HasAllocation = false; // at least one in/out allocation?
1027593a894650e81be54173106ec266f0311cebebd3Stephen Hines
1028c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  const RSExportForEach::InVec     &Ins     = EF->getIns();
1029c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  const RSExportForEach::InTypeVec &InTypes = EF->getInTypes();
1030c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  const RSExportType               *OET     = EF->getOutType();
1031d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  const RSExportRecordType         *ERT     = EF->getParamPacketType();
1032d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
1033d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mState->beginForEach(EF);
1034d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
1035d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  for (RSExportForEach::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
1036d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross       BI != EI; BI++) {
1037d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mState->addForEachIn(EF, *BI);
1038d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  }
1039c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
1040c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  if (Ins.size() == 1) {
1041fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross    HasAllocation = true;
1042d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (!mCollecting)
1043d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      Args.push_back(std::make_pair("Allocation", "ain"));
1044c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  } else if (Ins.size() > 1) {
1045fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross    HasAllocation = true;
1046d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (!mCollecting) {
1047d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      for (RSExportForEach::InIter BI = Ins.begin(), EI = Ins.end(); BI != EI;
1048d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross           BI++) {
1049d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        Args.push_back(std::make_pair("Allocation",
1050d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                      "ain_" + (*BI)->getName().str()));
1051d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      }
1052c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    }
1053c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  }
1054c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
1055fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross  if (EF->hasOut() || EF->hasReturn()) {
1056fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross    HasAllocation = true;
1057d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (!mCollecting)
1058d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      Args.push_back(std::make_pair("Allocation", "aout"));
1059fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross  }
1060b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
1061b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  if (ERT) {
1062b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    for (RSExportForEach::const_param_iterator I = EF->params_begin(),
10632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                               E = EF->params_end();
10642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet         I != E; I++) {
1065d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      mState->addForEachParam(EF, (*I)->getType());
1066d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      if (!mCollecting)
1067d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        Args.push_back(
1068d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross            std::make_pair(GetTypeName((*I)->getType()), (*I)->getName()));
1069593a894650e81be54173106ec266f0311cebebd3Stephen Hines    }
1070593a894650e81be54173106ec266f0311cebebd3Stephen Hines  }
1071593a894650e81be54173106ec266f0311cebebd3Stephen Hines
1072b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray  if (mRSContext->getTargetAPI() >= SLANG_JB_MR1_TARGET_API) {
1073d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mState->addForEachSignatureMetadata(EF, EF->getSignatureMetadata());
1074b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray
1075d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (!mCollecting) {
1076d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      startFunction(AM_Public, false, "Script.KernelID",
1077d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                    "getKernelID_" + EF->getName(), 0);
1078b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray
1079d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      // TODO: add element checking
1080d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      mOut.indent() << "return createKernelID(" << RS_EXPORT_FOREACH_INDEX_PREFIX
1081d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                    << EF->getName() << ", " << EF->getSignatureMetadata()
1082d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                    << ", null, null);\n";
1083d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
1084d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      endFunction();
1085d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    }
1086b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray  }
1087b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray
1088d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (!mCollecting) {
1089d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (mRSContext->getTargetAPI() >= SLANG_JB_MR2_TARGET_API) {
1090d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      if (HasAllocation) {
1091d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        startFunction(AM_Public, false, "void", "forEach_" + EF->getName(), Args);
109250974740c0c5c52dd766264139a01702fbc138afStephen Hines
1093d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        mOut.indent() << "forEach_" << EF->getName();
1094d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        mOut << "(";
109550974740c0c5c52dd766264139a01702fbc138afStephen Hines
1096d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        if (Ins.size() == 1) {
1097d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross          mOut << "ain, ";
1098c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
1099d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        } else if (Ins.size() > 1) {
1100d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross          for (RSExportForEach::InIter BI = Ins.begin(), EI = Ins.end(); BI != EI;
1101d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross               BI++) {
1102c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
1103d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross            mOut << "ain_" << (*BI)->getName().str() << ", ";
1104d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross          }
1105fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross        }
110650974740c0c5c52dd766264139a01702fbc138afStephen Hines
1107d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        if (EF->hasOut() || EF->hasReturn()) {
1108d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross          mOut << "aout, ";
1109d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        }
111050974740c0c5c52dd766264139a01702fbc138afStephen Hines
1111d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        if (EF->hasUsrData()) {
1112d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross          mOut << Args.back().second << ", ";
1113d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        }
111450974740c0c5c52dd766264139a01702fbc138afStephen Hines
1115d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        // No clipped bounds to pass in.
1116d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        mOut << "null);\n";
111750974740c0c5c52dd766264139a01702fbc138afStephen Hines
1118d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        endFunction();
1119d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      }
112050974740c0c5c52dd766264139a01702fbc138afStephen Hines
1121d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      // Add the clipped kernel parameters to the Args list.
1122d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      Args.push_back(std::make_pair("Script.LaunchOptions", "sc"));
1123d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    }
112450974740c0c5c52dd766264139a01702fbc138afStephen Hines  }
112550974740c0c5c52dd766264139a01702fbc138afStephen Hines
1126d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (!mCollecting) {
1127d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    startFunction(AM_Public, false, "void", "forEach_" + EF->getName(), Args);
1128593a894650e81be54173106ec266f0311cebebd3Stephen Hines
1129d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (InTypes.size() == 1) {
1130d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      if (InTypes.front() != nullptr) {
1131d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        genTypeCheck(InTypes.front(), "ain");
1132d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      }
1133c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
1134d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    } else if (InTypes.size() > 1) {
1135d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      size_t Index = 0;
1136d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      for (RSExportForEach::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
1137d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross           BI != EI; BI++, ++Index) {
1138c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
1139d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        if (*BI != nullptr) {
1140d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross          genTypeCheck(*BI, ("ain_" + Ins[Index]->getName()).str().c_str());
1141d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        }
1142c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      }
1143c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    }
1144c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
1145d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (OET) {
1146d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      genTypeCheck(OET, "aout");
1147d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    }
1148593a894650e81be54173106ec266f0311cebebd3Stephen Hines
1149d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (Ins.size() == 1 && (EF->hasOut() || EF->hasReturn())) {
1150d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      mOut.indent() << "Type t0, t1;";
1151d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      genPairwiseDimCheck("ain", "aout");
1152c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
1153d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    } else if (Ins.size() > 1) {
1154d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      mOut.indent() << "Type t0, t1;";
1155c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
1156d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      std::string In0Name = "ain_" + Ins[0]->getName().str();
1157c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
1158d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      for (size_t index = 1; index < Ins.size(); ++index) {
1159d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        genPairwiseDimCheck(In0Name, "ain_" + Ins[index]->getName().str());
1160d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      }
1161c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
1162d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      if (EF->hasOut() || EF->hasReturn()) {
1163d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        genPairwiseDimCheck(In0Name, "aout");
1164d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      }
1165c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    }
1166593a894650e81be54173106ec266f0311cebebd3Stephen Hines  }
1167593a894650e81be54173106ec266f0311cebebd3Stephen Hines
1168b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  std::string FieldPackerName = EF->getName() + "_fp";
1169b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  if (ERT) {
1170d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    // NOTE: This type isn't on the RSContext::export_types* list.
1171d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mState->declareRecord(ERT, false);
1172d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
1173d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (genCreateFieldPacker(ERT, FieldPackerName.c_str(),
1174d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                             mState->getRecord32(ERT).getRecordAllocSize())) {
11755abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes      genPackVarOfType(ERT, nullptr, FieldPackerName.c_str());
1176b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    }
1177b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  }
1178d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
1179d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mState->endForEach();
1180d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
1181d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (mCollecting)
1182d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    return;
1183d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
1184f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "forEach(" << RS_EXPORT_FOREACH_INDEX_PREFIX
1185f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << EF->getName();
1186b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
1187c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  if (Ins.size() == 1) {
1188f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << ", ain";
1189c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  } else if (Ins.size() > 1) {
1190c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    mOut << ", new Allocation[]{ain_" << Ins[0]->getName().str();
1191c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
1192c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    for (size_t index = 1; index < Ins.size(); ++index) {
1193c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      mOut << ", ain_" << Ins[index]->getName().str();
1194c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    }
1195c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
1196c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    mOut << "}";
1197c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
1198c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  } else {
1199c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    mOut << ", (Allocation) null";
1200c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  }
1201b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
12029ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines  if (EF->hasOut() || EF->hasReturn())
1203f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << ", aout";
1204b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  else
1205f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << ", null";
1206b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
1207b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  if (EF->hasUsrData())
1208f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << ", " << FieldPackerName;
1209b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  else
1210f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << ", null";
1211b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
121250974740c0c5c52dd766264139a01702fbc138afStephen Hines  if (mRSContext->getTargetAPI() >= SLANG_JB_MR2_TARGET_API) {
1213f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << ", sc);\n";
121450974740c0c5c52dd766264139a01702fbc138afStephen Hines  } else {
1215f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << ");\n";
121650974740c0c5c52dd766264139a01702fbc138afStephen Hines  }
1217b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
12182e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
1219593a894650e81be54173106ec266f0311cebebd3Stephen Hines}
1220593a894650e81be54173106ec266f0311cebebd3Stephen Hines
1221277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//////////////////////////////////////////////////////////////////////////////////////////////////////
1222277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1223277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// Reductions with certain legal result types can only be reflected for NDK, not for Java.
12241c6bf88e098c767c3cd445f2c2514f0598d91501David Grossbool RSReflectionJava::exportableReduce(const RSExportType *ResultType) {
1225277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const RSExportType *CheckType = ResultType;
1226277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  if (ResultType->getClass() == RSExportType::ExportClassConstantArray)
1227277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    CheckType = static_cast<const RSExportConstantArrayType *>(ResultType)->getElementType();
1228277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  if (CheckType->getClass() == RSExportType::ExportClassRecord) {
1229277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    // No Java reflection for struct until http://b/22236498 is resolved.
1230277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    return false;
1231277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1232277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1233277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  return true;
1234277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1235277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1236277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Grossnamespace {
1237277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Grossenum MappingComment { MappingCommentWithoutType, MappingCommentWithCType };
1238277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1239277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// OUTPUTS
1240277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//   InputParamName      = name to use for input parameter
1241277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//   InputMappingComment = text showing the mapping from InputParamName to the corresponding
1242277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//                           accumulator function parameter name (and possibly type)
1243277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// INPUTS
1244277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//   NamePrefix          = beginning of parameter name (e.g., "in")
1245277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//   MappingComment      = whether or not InputMappingComment should contain type
1246277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//   ER                  = description of the reduction
1247277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//   InIdx               = which input (numbered from zero)
12481c6bf88e098c767c3cd445f2c2514f0598d91501David Grossvoid getReduceInputStrings(std::string &InputParamName, std::string &InputMappingComment,
12491c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                           const std::string &NamePrefix, MappingComment Mapping,
12501c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                           const RSExportReduce *ER, size_t InIdx) {
1251277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  InputParamName = NamePrefix + std::to_string(InIdx+1);
1252277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  std::string TypeString;
1253277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  if (Mapping == MappingCommentWithCType) {
1254277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const RSExportType *InType = ER->getAccumulatorInTypes()[InIdx];
1255277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (InType->getClass() == RSExportType::ExportClassRecord) {
1256277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      // convertToRTD doesn't understand this type
1257277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      TypeString = "/* struct <> */ ";
1258277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    } else {
1259277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      RSReflectionTypeData InTypeData;
1260277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      ER->getAccumulatorInTypes()[InIdx]->convertToRTD(&InTypeData);
1261277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      slangAssert(InTypeData.type->s_name != nullptr);
1262277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      if (InTypeData.vecSize > 1) {
1263277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        TypeString = InTypeData.type->s_name + std::to_string(InTypeData.vecSize) + " ";
1264277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      } else {
1265277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        TypeString = InTypeData.type->s_name + std::string(" ");
1266277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      }
1267277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1268277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1269277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  InputMappingComment = InputParamName + " = \"" + TypeString + std::string(ER->getAccumulatorIns()[InIdx]->getName()) + "\"";
1270277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1271277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1272277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross} // end anonymous namespace
1273277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1274d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross// Keep this in sync with Reduce analysis in ReflectionState::declareReduce().
12751c6bf88e098c767c3cd445f2c2514f0598d91501David Grossvoid RSReflectionJava::genExportReduce(const RSExportReduce *ER) {
1276d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  const bool IsExportable = exportableReduce(ER->getResultType());
1277d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
1278d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // Need to track even a non-exportable reduce, both so that we get
1279d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // the count of reduction kernels correct, and so that we can
1280d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // intelligently diagnose cases where 32-bit and 64-bit compiles
1281d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // disagree as to whether a reduction kernel is exportable.
1282d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mState->declareReduce(ER, IsExportable);
1283d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
1284d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (!IsExportable || mCollecting)
1285277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    return;
1286277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1287277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Generate the reflected function index.
12881c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  mOut.indent() << "private final static int " << RS_EXPORT_REDUCE_INDEX_PREFIX
12891c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                << ER->getNameReduce() << " = " << getNextExportReduceSlot()
1290277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                << ";\n";
1291277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1292277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  /****** remember resultSvType generation **********************************************************/
1293277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1294277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Two variants of reduce_* entry points get generated.
1295277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Array variant:
1296277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  //   result_<resultSvType> reduce_<name>(<devecSiIn1Type>[] in1, ..., <devecSiInNType>[] inN)
1297277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Allocation variant:
1298277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  //   result_<resultSvType> reduce_<name>(Allocation in1, ..., Allocation inN)
1299277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  //   result_<resultSvType> reduce_<name>(Allocation in1, ..., Allocation inN, Script.LaunchOptions sc)
1300277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
13011c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  genExportReduceArrayVariant(ER);
13021c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  genExportReduceAllocationVariant(ER);
1303277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1304277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
13051c6bf88e098c767c3cd445f2c2514f0598d91501David Grossvoid RSReflectionJava::genExportReduceArrayVariant(const RSExportReduce *ER) {
1306277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Analysis of result type.  Returns early if result type is not
1307277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // suitable for array method reflection.
1308277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const RSExportType *const ResultType = ER->getResultType();
1309277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  auto ResultTypeClass = ResultType->getClass();
1310277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  switch (ResultTypeClass) {
1311277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassConstantArray:
1312277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassMatrix:
1313277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassPrimitive:
1314277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassVector:
1315277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        // Ok
1316277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        break;
1317277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1318277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassPointer:
1319277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        slangAssert(!"Should not get here with pointer type");
1320277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        return;
1321277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1322277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassRecord:
1323277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        // TODO: convertToRTD() cannot handle this.  Why not?
1324277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        return;
1325277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1326277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      default:
1327277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        slangAssert(!"Unknown export class");
1328277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        return;
1329277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1330277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  RSReflectionTypeData ResultTypeData;
1331277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  ResultType->convertToRTD(&ResultTypeData);
1332277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  if (!ResultTypeData.type->java_name || !ResultTypeData.type->java_array_element_name ||
1333277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      (ResultTypeData.vecSize > 1 && !ResultTypeData.type->rs_java_vector_prefix)) {
1334991096ff0ab7d2dc124994c0a40290212de349bdDavid Gross    slangAssert(false);
1335277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    return;
1336277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
13371c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  const std::string ResultTypeName = GetReduceResultTypeName(ER);
1338277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1339277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Analysis of inputs.  Returns early if some input type is not
1340277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // suitable for array method reflection.
1341277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  llvm::SmallVector<RSReflectionTypeData, 1> InsTypeData;
1342277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  ArgTy Args;
1343277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const auto &Ins = ER->getAccumulatorIns();
1344277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const auto &InTypes = ER->getAccumulatorInTypes();
1345277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  slangAssert(Ins.size() == InTypes.size());
1346277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  InsTypeData.resize(Ins.size());
1347277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  llvm::SmallVector<std::string, 1> InComments;
1348277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (size_t InIdx = 0, InEnd = Ins.size(); InIdx < InEnd; ++InIdx) {
1349277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const RSExportType *const InType = InTypes[InIdx];
1350277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    switch (InType->getClass()) {
1351277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassMatrix:
1352277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassPrimitive:
1353277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassVector:
1354277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        // Ok
1355277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        break;
1356277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1357277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassConstantArray:
1358277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        // No
1359277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        return;
1360277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1361277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassPointer:
1362277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        slangAssert(!"Should not get here with pointer type");
1363277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        return;
1364277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1365277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassRecord:
1366277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        // TODO: convertToRTD() cannot handle this.  Why not?
1367277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        return;
1368277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1369277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      default:
1370277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        slangAssert(!"Unknown export class");
1371277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        return;
1372277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1373277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1374277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    RSReflectionTypeData &InTypeData = InsTypeData[InIdx];
1375277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    InType->convertToRTD(&InTypeData);
1376277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (!InTypeData.type->java_name || !InTypeData.type->java_array_element_name ||
1377277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        (InTypeData.vecSize > 1 && !InTypeData.type->rs_java_vector_prefix)) {
1378277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      return;
1379277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1380277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1381277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    std::string InputParamName, InputComment;
13821c6bf88e098c767c3cd445f2c2514f0598d91501David Gross    getReduceInputStrings(InputParamName, InputComment, "in", MappingCommentWithoutType, ER, InIdx);
1383277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (InTypeData.vecSize > 1)
1384277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      InputComment += (", flattened " + std::to_string(InTypeData.vecSize) + "-vectors");
1385277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    InComments.push_back(InputComment);
1386277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1387277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const std::string InputTypeName = std::string(InTypeData.type->java_array_element_name) + "[]";
1388277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    Args.push_back(std::make_pair(InputTypeName, InputParamName));
1389277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1390277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1391277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const std::string MethodName = "reduce_" + ER->getNameReduce();
1392277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1393277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // result_<resultSvType> reduce_<name>(<devecSiIn1Type>[] in1, ..., <devecSiInNType>[] inN)
1394277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1395277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (const std::string &InComment : InComments)
1396277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << "// " << InComment << "\n";
1397277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  startFunction(AM_Public, false, ResultTypeName.c_str(), MethodName, Args);
1398277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  slangAssert(Ins.size() == InTypes.size());
1399277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  slangAssert(Ins.size() == InsTypeData.size());
1400277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  slangAssert(Ins.size() == Args.size());
14011381ae7c081ab151e78184501f757f517fe6c2a9David Gross  std::string In1Length;
14021381ae7c081ab151e78184501f757f517fe6c2a9David Gross  std::string InputAllocationOutgoingArgumentList;
14032b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  std::vector<std::string> InputAllocationNames;
1404277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (size_t InIdx = 0, InEnd = Ins.size(); InIdx < InEnd; ++InIdx) {
1405277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const std::string &ArgName = Args[InIdx].second;
1406277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    genNullArrayCheck(ArgName);
1407277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    std::string InLength = ArgName + ".length";
1408277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const uint32_t VecSize = InsTypeData[InIdx].vecSize;
1409277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (VecSize > 1) {
1410277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      InLength += " / " + std::to_string(VecSize);
1411277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      genVectorLengthCompatibilityCheck(ArgName, VecSize);
1412277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1413277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (InIdx == 0) {
14141381ae7c081ab151e78184501f757f517fe6c2a9David Gross      In1Length = InLength;
1415277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    } else {
1416277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.indent() << "// Verify that input array lengths are the same.\n";
14171381ae7c081ab151e78184501f757f517fe6c2a9David Gross      mOut.indent() << "if (" << In1Length << " != " << InLength << ") {\n";
1418277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.indent() << "    throw new RSRuntimeException(\"Array length mismatch "
1419277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                    << "between parameters \\\"" << Args[0].second << "\\\" and \\\"" << ArgName
1420277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                    << "\\\"!\");\n";
1421277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.indent() << "}\n";
1422277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1423277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    // Create a temporary input allocation
1424277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const std::string TempName = "a" + ArgName;
1425277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << "Allocation " << TempName << " = Allocation.createSized("
1426277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                  << SAVED_RS_REFERENCE << ", "
1427277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                  << RS_ELEM_PREFIX << InTypes[InIdx]->getElementName() << ", "
14281381ae7c081ab151e78184501f757f517fe6c2a9David Gross                  << InLength << ");\n";
1429277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << TempName << ".setAutoPadding(true);\n";
14301381ae7c081ab151e78184501f757f517fe6c2a9David Gross    mOut.indent() << TempName << ".copyFrom(" << ArgName << ");\n";
1431277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    // ... and put that input allocation on the outgoing argument list
1432277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (!InputAllocationOutgoingArgumentList.empty())
1433277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      InputAllocationOutgoingArgumentList += ", ";
1434277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    InputAllocationOutgoingArgumentList += TempName;
14352b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross    // ... and keep track of it for setting result.mTempIns
14362b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross    InputAllocationNames.push_back(TempName);
1437277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
14381381ae7c081ab151e78184501f757f517fe6c2a9David Gross
1439277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut << "\n";
14402b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << ResultTypeName << " result = " << MethodName << "(" << InputAllocationOutgoingArgumentList << ", null);\n";
14412b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  if (!InputAllocationNames.empty()) {
14422b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross    mOut.indent() << "result.mTempIns = new Allocation[]{";
14432b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross    bool EmittedFirst = false;
14442b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross    for (const std::string &InputAllocationName : InputAllocationNames) {
14452b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      if (!EmittedFirst) {
14462b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross        EmittedFirst = true;
14472b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      } else {
14482b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross        mOut << ", ";
14492b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      }
14502b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      mOut << InputAllocationName;
14512b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross    }
14522b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross    mOut << "};\n";
14532b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  }
14542b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "return result;\n";
1455277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  endFunction();
1456277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1457277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
14581c6bf88e098c767c3cd445f2c2514f0598d91501David Grossvoid RSReflectionJava::genExportReduceAllocationVariant(const RSExportReduce *ER) {
1459277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const auto &Ins = ER->getAccumulatorIns();
1460277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const auto &InTypes = ER->getAccumulatorInTypes();
1461277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const RSExportType *ResultType = ER->getResultType();
1462277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1463277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  llvm::SmallVector<std::string, 1> InComments;
1464277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  ArgTy Args;
1465277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (size_t InIdx = 0, InEnd = Ins.size(); InIdx < InEnd; ++InIdx) {
1466277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    std::string InputParamName, InputComment;
14671c6bf88e098c767c3cd445f2c2514f0598d91501David Gross    getReduceInputStrings(InputParamName, InputComment, "ain", MappingCommentWithCType, ER, InIdx);
1468277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    InComments.push_back(InputComment);
1469277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    Args.push_back(std::make_pair("Allocation", InputParamName));
1470277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1471277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1472277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const std::string MethodName = "reduce_" + ER->getNameReduce();
14731c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  const std::string ResultTypeName = GetReduceResultTypeName(ER);
1474277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1475277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // result_<resultSvType> reduce_<name>(Allocation in1, ..., Allocation inN)
1476277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1477277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (const std::string &InComment : InComments)
1478277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << "// " << InComment << "\n";
1479277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  startFunction(AM_Public, false, ResultTypeName.c_str(), MethodName, Args);
1480277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << "return " << MethodName << "(";
1481277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  bool EmittedFirstArg = false;
1482277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (const auto &Arg : Args) {
1483277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (!EmittedFirstArg) {
1484277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      EmittedFirstArg = true;
1485277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    } else {
1486277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut << ", ";
1487277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1488277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut << Arg.second;
1489277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1490277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut << ", null);\n";
1491277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  endFunction();
1492277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1493277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // result_<resultSvType> reduce_<name>(Allocation in1, ..., Allocation inN, Script.LaunchOptions sc)
1494277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1495277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  static const char FormalOptionsName[] = "sc";
1496277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  Args.push_back(std::make_pair("Script.LaunchOptions", FormalOptionsName));
1497277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (const std::string &InComment : InComments)
1498277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << "// " << InComment << "\n";
1499277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  startFunction(AM_Public, false, ResultTypeName.c_str(), MethodName, Args);
1500277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const std::string &In0Name = Args[0].second;
1501277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Sanity-check inputs
1502277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  if (Ins.size() > 1)
1503277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << "Type t0, t1;\n";
1504277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (size_t InIdx = 0, InEnd = Ins.size(); InIdx < InEnd; ++InIdx) {
1505277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const std::string &InName = Args[InIdx].second;
1506277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    genTypeCheck(InTypes[InIdx], InName.c_str());
1507277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (InIdx > 0)
1508277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      genPairwiseDimCheck(In0Name.c_str(), InName.c_str());
1509277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1510277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Create a temporary output allocation
1511277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const char OutputAllocName[] = "aout";
1512277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const size_t OutputAllocLength =
1513277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      ResultType->getClass() == RSExportType::ExportClassConstantArray
1514277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      ? static_cast<const RSExportConstantArrayType *>(ResultType)->getNumElement()
1515277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      : 1;
1516277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << "Allocation " << OutputAllocName << " = Allocation.createSized("
1517277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                << SAVED_RS_REFERENCE << ", "
1518277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                << RS_ELEM_PREFIX << ResultType->getElementName() << ", "
1519277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                << OutputAllocLength << ");\n";
1520277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << OutputAllocName << ".setAutoPadding(true);\n";
1521277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Call the underlying reduce entry point
15221c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  mOut.indent() << "reduce(" << RS_EXPORT_REDUCE_INDEX_PREFIX << ER->getNameReduce()
1523277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                << ", new Allocation[]{" << In0Name;
1524277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (size_t InIdx = 1, InEnd = Ins.size(); InIdx < InEnd; ++InIdx)
1525277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut << ", " << Args[InIdx].second;
1526277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut << "}, " << OutputAllocName << ", " << FormalOptionsName << ");\n";
1527277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << "return new " << ResultTypeName << "(" << OutputAllocName << ");\n";
1528277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  endFunction();
1529277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1530277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1531277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Grossnamespace {
1532277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1533277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// When we've copied the Allocation to a Java array, how do we
1534277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// further process the elements of that array?
1535277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Grossenum MapFromAllocation {
1536277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  MapFromAllocationTrivial,  // no further processing
1537277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  MapFromAllocationPositive, // need to ensure elements are positive (range check)
1538277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  MapFromAllocationBoolean,  // need to convert elements from byte to boolean
1539277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  MapFromAllocationPromote   // need to zero extend elements
1540277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross};
1541277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1542277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// Return Java expression that maps from an Allocation element to a Java non-vector result.
1543277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//
1544277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// MFA                     = mapping kind
1545277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// ArrayElementTypeName    = type of InVal (having been copied out of Allocation to Java array)
1546277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// ReflectedScalarTypeName = type of mapped value
1547277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// InVal                   = input value that must be mapped
1548277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//
15491c6bf88e098c767c3cd445f2c2514f0598d91501David Grossstd::string genReduceResultMapping(MapFromAllocation MFA,
15501c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                   const std::string &ArrayElementTypeName,
15511c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                   const std::string &ReflectedScalarTypeName,
15521c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                   const char *InVal) {
1553277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  switch (MFA) {
1554277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    default:
1555277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      slangAssert(!"Unknown MapFromAllocation");
1556277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      // and fall through
1557277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    case MapFromAllocationPositive: // range checking must be done separately
1558277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    case MapFromAllocationTrivial:
1559277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      return InVal;
1560277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    case MapFromAllocationBoolean:
1561277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      return std::string(InVal) + std::string(" != 0");
1562277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    case MapFromAllocationPromote:
1563277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      return ZeroExtendValue(InVal,
1564277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                             ArrayElementTypeName,
1565277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                             ReflectedScalarTypeName);
1566277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1567277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1568277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1569277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// Return Java expression that maps from an Allocation element to a Java vector result.
1570277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//
1571277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// MFA                     = mapping kind
1572277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// ArrayElementTypeName    = type of InVal (having been copied out of Allocation to Java array)
1573277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// ReflectedScalarTypeName = type of mapped value
1574277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// VectorTypeName          = type of vector
1575277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// VectorElementCount      = number of elements in the vector
1576277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// InArray                 = input array containing vector elements
1577277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// InIdx                   = index of first vector element within InArray (or nullptr, if 0)
1578277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//
15791c6bf88e098c767c3cd445f2c2514f0598d91501David Grossstd::string genReduceResultVectorMapping(MapFromAllocation MFA,
15801c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                         const std::string &ArrayElementTypeName,
15811c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                         const std::string &ReflectedScalarTypeName,
15821c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                         const std::string &VectorTypeName,
15831c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                         unsigned VectorElementCount,
15841c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                         const char *InArray, const char *InIdx = nullptr) {
1585277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  std::string result = "new " + VectorTypeName + "(";
1586277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (unsigned VectorElementIdx = 0; VectorElementIdx < VectorElementCount; ++VectorElementIdx) {
1587277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (VectorElementIdx)
1588277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross     result += ", ";
1589277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1590277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    std::string ArrayElementName = std::string(InArray) + "[";
1591277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (InIdx)
1592277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      ArrayElementName += std::string(InIdx) + "+";
1593277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    ArrayElementName += std::to_string(VectorElementIdx) + "]";
1594277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
15951c6bf88e098c767c3cd445f2c2514f0598d91501David Gross    result += genReduceResultMapping(MFA, ArrayElementTypeName, ReflectedScalarTypeName,
15961c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                     ArrayElementName.c_str());
1597277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1598277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  result += ")";
1599277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  return result;
1600277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1601277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
16021c6bf88e098c767c3cd445f2c2514f0598d91501David Grossvoid genReduceResultRangeCheck(GeneratedFile &Out, const char *InVal) {
1603277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  Out.indent() << "if (" << InVal << " < 0)\n";
1604277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  Out.indent() << "    throw new RSRuntimeException(\"Result is not representible in Java\");\n";
1605277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1606277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1607277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross} // end anonymous namespace
1608277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
16091c6bf88e098c767c3cd445f2c2514f0598d91501David Grossvoid RSReflectionJava::genExportReduceResultType(const RSExportType *ResultType) {
16101c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  if (!exportableReduce(ResultType))
1611277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    return;
1612277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
16131c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  const std::string ClassName = GetReduceResultTypeName(ResultType);
16142b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  const std::string GetMethodReturnTypeName = GetTypeName(ResultType);
1615277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << "// To obtain the result, invoke get(), which blocks\n";
1616277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << "// until the asynchronously-launched operation has completed.\n";
1617277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << "public static class " << ClassName;
1618277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.startBlock();
16192b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  startFunction(AM_Public, false, GetMethodReturnTypeName.c_str(), "get", 0);
1620277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1621277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  RSReflectionTypeData TypeData;
1622277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  ResultType->convertToRTD(&TypeData);
1623277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1624277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const std::string UnbracketedResultTypeName =
1625277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      GetTypeName(ResultType, TypeNameDefault & ~TypeNameWithConstantArrayBrackets);
1626277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const std::string ReflectedScalarTypeName = TypeData.type->java_name;
1627991096ff0ab7d2dc124994c0a40290212de349bdDavid Gross  // Note: MATRIX* types do not have a java_array_element_name
1628277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const std::string ArrayElementTypeName =
1629277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      TypeData.type->java_array_element_name
1630277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      ? std::string(TypeData.type->java_array_element_name)
1631277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      : ReflectedScalarTypeName;
1632277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1633277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  MapFromAllocation MFA = MapFromAllocationTrivial;
1634277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  if (std::string(TypeData.type->rs_type) == "UNSIGNED_64")
1635277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    MFA = MapFromAllocationPositive;
1636277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  else if (ReflectedScalarTypeName == "boolean")
1637277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    MFA = MapFromAllocationBoolean;
1638277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  else if (ReflectedScalarTypeName != ArrayElementTypeName)
1639277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    MFA = MapFromAllocationPromote;
1640277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
16412b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "if (!mGotResult)";
16422b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.startBlock();
16432b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross
1644277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  if (TypeData.vecSize == 1) { // result type is non-vector
1645277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    // <ArrayElementType>[] outArray = new <ArrayElementType>[1];
1646277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    // mOut.copyTo(outArray);
1647277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << ArrayElementTypeName << "[] outArray = new " << ArrayElementTypeName
1648277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                  << "[" << std::max(TypeData.arraySize, 1U) << "];\n";
1649277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << "mOut.copyTo(outArray);\n";
1650277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (TypeData.arraySize == 0) { // result type is non-array non-vector
16512b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      // mResult = outArray[0]; // but there are several special cases
1652277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      if (MFA == MapFromAllocationPositive)
16531c6bf88e098c767c3cd445f2c2514f0598d91501David Gross        genReduceResultRangeCheck(mOut, "outArray[0]");
16542b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      mOut.indent() << "mResult = "
16551c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                    << genReduceResultMapping(MFA, ArrayElementTypeName, ReflectedScalarTypeName,
16561c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                              "outArray[0]")
1657277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                    << ";\n";
1658277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    } else { // result type is array of non-vector
1659277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      if (MFA == MapFromAllocationTrivial) {
16602b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross        // mResult = outArray;
16612b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross        mOut.indent() << "mResult = outArray;\n";
1662277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      } else {
1663277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        // <ResultType> result = new <UnbracketedResultType>[<ArrayElementCount>];
1664277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        // for (unsigned Idx = 0; Idx < <ArrayElementCount>; ++Idx)
1665277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        //   result[Idx] = <Transform>(outArray[Idx]);
16662b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross        // mResult = result; // but there are several special cases
1667277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        if (MFA != MapFromAllocationPositive) {
1668277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross          mOut.indent() << GetTypeName(ResultType) << " result = new "
1669277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                        << UnbracketedResultTypeName
1670277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                        << "[" << TypeData.arraySize << "];\n";
1671277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        }
1672277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        mOut.indent() << "for (int Idx = 0; Idx < " << TypeData.arraySize << "; ++Idx)";
1673277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        mOut.startBlock();
1674277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        if (MFA == MapFromAllocationPositive) {
16751c6bf88e098c767c3cd445f2c2514f0598d91501David Gross          genReduceResultRangeCheck(mOut, "outArray[Idx]");
1676277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        } else {
1677277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross          mOut.indent() << "result[Idx] = "
16781c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                        << genReduceResultMapping(MFA, ArrayElementTypeName, ReflectedScalarTypeName,
1679277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                                                     "outArray[Idx]")
1680277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                        << ";\n";
1681277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        }
1682277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        mOut.endBlock();
16832b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross        mOut.indent() << "mResult = " << (MFA == MapFromAllocationPositive ? "outArray" : "result") << ";\n";
1684277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      }
1685277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1686277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  } else { // result type is vector or array of vector
1687277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    // <ArrayElementType>[] outArray = new <ArrayElementType>[<VectorElementCount> * <ArrayElementCount>];
1688277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    // mOut.copyTo(outArray);
1689277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const unsigned VectorElementCount = TypeData.vecSize;
1690277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const unsigned OutArrayElementCount = VectorElementCount * std::max(TypeData.arraySize, 1U);
1691277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << ArrayElementTypeName << "[] outArray = new " << ArrayElementTypeName
1692277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                  << "[" << OutArrayElementCount << "];\n";
1693277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << "mOut.copyTo(outArray);\n";
1694277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (MFA == MapFromAllocationPositive) {
1695277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.indent() << "for (int Idx = 0; Idx < " << OutArrayElementCount << "; ++Idx)";
1696277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.startBlock();
16971c6bf88e098c767c3cd445f2c2514f0598d91501David Gross      genReduceResultRangeCheck(mOut, "outArray[Idx]");
1698277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.endBlock();
1699277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1700277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (TypeData.arraySize == 0) { // result type is vector
17012b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      // mResult = new <ResultType>(outArray[0], outArray[1] ...); // but there are several special cases
17022b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      mOut.indent() << "mResult = "
17031c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                    << genReduceResultVectorMapping(MFA,
17041c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                                    ArrayElementTypeName, ReflectedScalarTypeName,
17051c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                                    GetTypeName(ResultType), VectorElementCount,
17061c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                                    "outArray")
1707277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                    << ";\n";
1708277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    } else { // result type is array of vector
1709277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      // <ResultType> result = new <UnbracketedResultType>[<ArrayElementCount>];
1710277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      // for (unsigned Idx = 0; Idx < <ArrayElementCount>; ++Idx)
1711277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      //   result[Idx] = new <UnbracketedResultType>(outArray[<ArrayElementCount>*Idx+0],
1712277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      //                                             outArray[<ArrayElementCount>*Idx+1]...);
17132b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      // mResult = result; // but there are several special cases
1714277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.indent() << GetTypeName(ResultType) << " result = new "
1715277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                    << UnbracketedResultTypeName
1716277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                    << "[" << TypeData.arraySize << "];\n";
1717277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.indent() << "for (int Idx = 0; Idx < " << TypeData.arraySize << "; ++Idx)";
1718277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.startBlock();
1719277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.indent() << "result[Idx] = "
17201c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                    << genReduceResultVectorMapping(MFA,
17211c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                                    ArrayElementTypeName, ReflectedScalarTypeName,
17221c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                                    UnbracketedResultTypeName, VectorElementCount,
17231c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                                    "outArray", (std::to_string(VectorElementCount) + "*Idx").c_str())
1724277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                    << ";\n";
1725277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.endBlock();
17262b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      mOut.indent() << "mResult = result;\n";
1727277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1728277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1729277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
17302b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "mOut.destroy();\n";
17312b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "mOut = null;  // make Java object eligible for garbage collection\n";
17322b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "if (mTempIns != null)";
17332b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.startBlock();
17342b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "for (Allocation tempIn : mTempIns)";
17352b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.startBlock();
17362b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "tempIn.destroy();\n";
17372b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.endBlock();
17382b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "mTempIns = null;  // make Java objects eligible for garbage collection\n";
17392b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.endBlock();
17402b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "mGotResult = true;\n";
17412b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.endBlock();
17422b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross
17432b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "return mResult;\n";
1744277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  endFunction();
17452b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross
1746277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  startFunction(AM_Private, false, nullptr, ClassName, 1, "Allocation", "out");
1747277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // TODO: Generate allocation type check and size check?  Or move
1748277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // responsibility for instantiating the Allocation here, instead of
1749277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // the reduce_* method?
17502b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "mTempIns = null;\n";
1751277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << "mOut = out;\n";
17522b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "mGotResult = false;\n";
1753277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  endFunction();
17542b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "private Allocation[] mTempIns;\n";
1755277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << "private Allocation mOut;\n";
17562b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  // TODO: If result is reference type rather than primitive type, we
17572b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  // could omit mGotResult and use mResult==null to indicate that we
17582b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  // haven't obtained the result yet.
17592b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "private boolean mGotResult;\n";
17602b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "private " << GetMethodReturnTypeName << " mResult;\n";
1761277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.endBlock();
1762277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1763277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1764277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//////////////////////////////////////////////////////////////////////////////////////////////////////
1765277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
17662e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeInstanceFromPointer(const RSExportType *ET) {
176748b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  if (ET->getClass() == RSExportType::ExportClassPointer) {
17689ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    // For pointer parameters to original forEach kernels.
176948b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    const RSExportPointerType *EPT =
17702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportPointerType *>(ET);
17712e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genTypeInstance(EPT->getPointeeType());
17729ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines  } else {
17739ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    // For handling pass-by-value kernel parameters.
17742e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genTypeInstance(ET);
1775a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines  }
1776a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines}
177748b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
17782e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeInstance(const RSExportType *ET) {
1779a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines  switch (ET->getClass()) {
17802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive:
17812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector:
17822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray: {
17832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::string TypeName = ET->getElementName();
17842e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    if (addTypeNameForElement(TypeName)) {
1785f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << RS_ELEM_PREFIX << TypeName << " = Element." << TypeName
1786f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << "(rs);\n";
1787a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines    }
17882ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
17892ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
179048b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
17912ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
17922ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::string ClassName = ET->getElementName();
17932e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    if (addTypeNameForElement(ClassName)) {
1794f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << RS_ELEM_PREFIX << ClassName << " = " << ClassName
1795f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ".createElement(rs);\n";
179648b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    }
17972ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
17982ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
1799a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines
18002ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default:
18012ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
180248b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  }
180348b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines}
180448b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
18052e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genFieldPackerInstance(const RSExportType *ET) {
18061f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  switch (ET->getClass()) {
18072ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive:
18082ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector:
18092ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray:
18102ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
18112ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::string TypeName = ET->getElementName();
18122e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    addTypeNameForFieldPacker(TypeName);
18132ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
18142ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
18151f6c331d622ac645ab68a016aa4c577998547373Stephen Hines
18162ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default:
18172ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
18181f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  }
18191f6c331d622ac645ab68a016aa4c577998547373Stephen Hines}
18201f6c331d622ac645ab68a016aa4c577998547373Stephen Hines
18212e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeCheck(const RSExportType *ET,
1822602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                    const char *VarName) {
1823f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "// check " << VarName << "\n";
182448b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
182548b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  if (ET->getClass() == RSExportType::ExportClassPointer) {
182648b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    const RSExportPointerType *EPT =
18272ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportPointerType *>(ET);
182848b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    ET = EPT->getPointeeType();
182948b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  }
183048b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
183148b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  std::string TypeName;
183248b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
183348b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  switch (ET->getClass()) {
18342ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive:
18352ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector:
18362ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
18372ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    TypeName = ET->getElementName();
18382ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
18392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
184048b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
18412ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default:
18422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
184348b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  }
184448b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
184548b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  if (!TypeName.empty()) {
1846f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "if (!" << VarName
1847f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << ".getType().getElement().isCompatible(" RS_ELEM_PREFIX
1848f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << TypeName << ")) {\n";
1849f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "    throw new RSRuntimeException(\"Type mismatch with "
1850f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << TypeName << "!\");\n";
1851f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "}\n";
185248b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  }
1853b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines}
1854b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
18552e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genPrimitiveTypeExportVariable(const RSExportVar *EV) {
1856602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet  slangAssert(
1857602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet      (EV->getType()->getClass() == RSExportType::ExportClassPrimitive) &&
1858602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet      "Variable should be type of primitive here");
18599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
18609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const RSExportPrimitiveType *EPT =
18612ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      static_cast<const RSExportPrimitiveType *>(EV->getType());
18620d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string TypeName = GetTypeName(EPT);
1863e2ead846c1d78a6e7108e521ffd15850bd9eed3cChih-Hung Hsieh  const std::string &VarName = EV->getName();
18649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
18652e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genPrivateExportVariable(TypeName, EV->getName());
18669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
18675d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines  if (EV->isConst()) {
1868f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "public final static " << TypeName
1869f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << " " RS_EXPORT_VAR_CONST_PREFIX << VarName << " = ";
18705d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines    const clang::APValue &Val = EV->getInit();
1871efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    genInitValue(Val, EPT->getType() == DataTypeBoolean);
1872f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << ";\n";
18735d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines  } else {
18745d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines    // set_*()
18751f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    // This must remain synchronized, since multiple Dalvik threads may
18761f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    // be calling setters.
18772e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    startFunction(AM_PublicSynchronized, false, "void", "set_" + VarName, 1,
18782e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  TypeName.c_str(), "v");
1879657d20afa621219c1eed72178d1325fd4409f458David Gross    if ((EPT->getElementSizeInBytes() < 4) || EV->isUnsigned()) {
18801f6c331d622ac645ab68a016aa4c577998547373Stephen Hines      // We create/cache a per-type FieldPacker. This allows us to reuse the
18811f6c331d622ac645ab68a016aa4c577998547373Stephen Hines      // validation logic (for catching negative inputs from Dalvik, as well
18821f6c331d622ac645ab68a016aa4c577998547373Stephen Hines      // as inputs that are too large to be represented in the unsigned type).
1883bcae1fe692a8c5d9225a9699a932380b5659a735Stephen Hines      // Sub-integer types are also handled specially here, so that we don't
1884bcae1fe692a8c5d9225a9699a932380b5659a735Stephen Hines      // overwrite bytes accidentally.
18851f6c331d622ac645ab68a016aa4c577998547373Stephen Hines      std::string ElemName = EPT->getElementName();
18861f6c331d622ac645ab68a016aa4c577998547373Stephen Hines      std::string FPName;
18871f6c331d622ac645ab68a016aa4c577998547373Stephen Hines      FPName = RS_FP_PREFIX + ElemName;
1888f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << "if (" << FPName << "!= null) {\n";
1889f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.increaseIndent();
1890f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << FPName << ".reset();\n";
1891f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.decreaseIndent();
1892f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << "} else {\n";
1893f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.increaseIndent();
1894657d20afa621219c1eed72178d1325fd4409f458David Gross      mOut.indent() << FPName << " = new FieldPacker(" << EPT->getElementSizeInBytes()
1895f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ");\n";
1896f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.decreaseIndent();
1897f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << "}\n";
18982e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
18992e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genPackVarOfType(EPT, "v", FPName.c_str());
1900f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
1901f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ", " << FPName << ");\n";
19021f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    } else {
1903f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
1904f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ", v);\n";
19051f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    }
19069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
19071f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    // Dalvik update comes last, since the input may be invalid (and hence
19081f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    // throw an exception).
1909f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
1910462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
19112e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    endFunction();
19129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1913462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
19142e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetExportVariable(TypeName, VarName);
19152e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetFieldID(VarName);
1916462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
1917462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1918efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouilletvoid RSReflectionJava::genInitValue(const clang::APValue &Val, bool asBool) {
1919efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  switch (Val.getKind()) {
1920efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::Int: {
1921e2ead846c1d78a6e7108e521ffd15850bd9eed3cChih-Hung Hsieh    const llvm::APInt &api = Val.getInt();
1922efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    if (asBool) {
1923f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut << ((api.getSExtValue() == 0) ? "false" : "true");
1924efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    } else {
1925efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      // TODO: Handle unsigned correctly
1926f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut << api.getSExtValue();
1927efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      if (api.getBitWidth() > 32) {
1928f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        mOut << "L";
1929efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      }
1930efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    }
1931efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    break;
1932efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  }
1933efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
1934efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::Float: {
1935e2ead846c1d78a6e7108e521ffd15850bd9eed3cChih-Hung Hsieh    const llvm::APFloat &apf = Val.getFloat();
1936efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    llvm::SmallString<30> s;
1937efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    apf.toString(s);
1938f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << s.c_str();
1939efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) {
1940efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      if (s.count('.') == 0) {
1941f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        mOut << ".f";
1942efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      } else {
1943f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        mOut << "f";
1944efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      }
1945efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    }
1946efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    break;
1947efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  }
1948efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
1949efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::ComplexInt:
1950efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::ComplexFloat:
1951efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::LValue:
1952efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::Vector: {
1953efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    slangAssert(false && "Primitive type cannot have such kind of initializer");
1954efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    break;
1955efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  }
1956efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
1957efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  default: { slangAssert(false && "Unknown kind of initializer"); }
1958efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  }
1959efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet}
1960efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
19612e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genPointerTypeExportVariable(const RSExportVar *EV) {
19629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const RSExportType *ET = EV->getType();
19639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const RSExportType *PointeeType;
1964462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
19656e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert((ET->getClass() == RSExportType::ExportClassPointer) &&
19666e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines              "Variable should be type of pointer here");
1967462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
19682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  PointeeType = static_cast<const RSExportPointerType *>(ET)->getPointeeType();
19690d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string TypeName = GetTypeName(ET);
1970e2ead846c1d78a6e7108e521ffd15850bd9eed3cChih-Hung Hsieh  const std::string &VarName = EV->getName();
1971462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
19722e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genPrivateExportVariable(TypeName, VarName);
1973462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
197489273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang  // bind_*()
19752e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, false, "void", "bind_" + VarName, 1,
19762e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                TypeName.c_str(), "v");
1977462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1978f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
1979f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (v == null) bindAllocation(null, "
1980f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << RS_EXPORT_VAR_INDEX_PREFIX << VarName << ");\n";
1981462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1982f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  if (PointeeType->getClass() == RSExportType::ExportClassRecord) {
1983f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "else bindAllocation(v.getAllocation(), "
1984f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << RS_EXPORT_VAR_INDEX_PREFIX << VarName << ");\n";
1985f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  } else {
1986f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "else bindAllocation(v, " << RS_EXPORT_VAR_INDEX_PREFIX
1987f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << VarName << ");\n";
1988f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  }
1989462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
19902e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
1991462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
19922e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetExportVariable(TypeName, VarName);
1993462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
1994462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
19952e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genVectorTypeExportVariable(const RSExportVar *EV) {
19966e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert((EV->getType()->getClass() == RSExportType::ExportClassVector) &&
19976e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines              "Variable should be type of vector here");
19989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
19990d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string TypeName = GetTypeName(EV->getType());
20000d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string VarName = EV->getName();
20019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
20022e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genPrivateExportVariable(TypeName, VarName);
2003657d20afa621219c1eed72178d1325fd4409f458David Gross  genSetExportVariable(TypeName, EV, 1);
20042e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetExportVariable(TypeName, VarName);
20052e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetFieldID(VarName);
2006462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2007462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
20082e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genMatrixTypeExportVariable(const RSExportVar *EV) {
20096e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert((EV->getType()->getClass() == RSExportType::ExportClassMatrix) &&
20106e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines              "Variable should be type of matrix here");
201192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
20122ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  const RSExportType *ET = EV->getType();
20130d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string TypeName = GetTypeName(ET);
2014e2ead846c1d78a6e7108e521ffd15850bd9eed3cChih-Hung Hsieh  const std::string &VarName = EV->getName();
201592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
20162e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genPrivateExportVariable(TypeName, VarName);
201792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
201892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang  // set_*()
201992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang  if (!EV->isConst()) {
20200d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines    const char *FieldPackerName = "fp";
20212e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    startFunction(AM_PublicSynchronized, false, "void", "set_" + VarName, 1,
20222e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  TypeName.c_str(), "v");
2023f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
202492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
2025d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (genCreateFieldPacker(ET, FieldPackerName, ReflectionState::NoVal32()))
20262e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genPackVarOfType(ET, "v", FieldPackerName);
2027f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "setVar(" RS_EXPORT_VAR_INDEX_PREFIX << VarName << ", "
2028f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << FieldPackerName << ");\n";
202992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
20302e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    endFunction();
203192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang  }
203292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
20332e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetExportVariable(TypeName, VarName);
20342e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetFieldID(VarName);
203592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang}
203692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
2037602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouilletvoid
2038d80e58b259c2febc4907aed4aca9d88d43bdd1a1David GrossRSReflectionJava::genConstantArrayTypeExportVariable(const RSExportVar *EV,
2039d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                                     ReflectionState::Val32 AllocSize32) {
2040657d20afa621219c1eed72178d1325fd4409f458David Gross  const RSExportType *const ET = EV->getType();
2041602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet  slangAssert(
2042657d20afa621219c1eed72178d1325fd4409f458David Gross      (ET->getClass() == RSExportType::ExportClassConstantArray) &&
2043602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet      "Variable should be type of constant array here");
20442e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang
20450d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string TypeName = GetTypeName(EV->getType());
20460d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string VarName = EV->getName();
20472e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang
20482e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genPrivateExportVariable(TypeName, VarName);
2049d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  genSetExportVariable(TypeName, EV,
2050d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                       static_cast<const RSExportConstantArrayType *>(ET)->getNumElement(),
2051d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                       AllocSize32);
20522e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetExportVariable(TypeName, VarName);
20532e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetFieldID(VarName);
20542e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang}
20552e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang
2056d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Grossvoid RSReflectionJava::genRecordTypeExportVariable(const RSExportVar *EV,
2057d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                                   ReflectionState::Val32 AllocSize32) {
20586e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert((EV->getType()->getClass() == RSExportType::ExportClassRecord) &&
20596e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines              "Variable should be type of struct here");
20609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
20610d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string TypeName = GetTypeName(EV->getType());
20620d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string VarName = EV->getName();
20639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
20642e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genPrivateExportVariable(TypeName, VarName);
2065d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  genSetExportVariable(TypeName, EV, 1, AllocSize32);
20662e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetExportVariable(TypeName, VarName);
20672e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetFieldID(VarName);
20680d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines}
20690d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines
20702e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genPrivateExportVariable(const std::string &TypeName,
2071602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                                const std::string &VarName) {
2072f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "private " << TypeName << " " << RS_EXPORT_VAR_PREFIX
2073f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << VarName << ";\n";
20740d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines}
20759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2076657d20afa621219c1eed72178d1325fd4409f458David Gross// Dimension = array element count; otherwise, 1.
20772e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genSetExportVariable(const std::string &TypeName,
2078657d20afa621219c1eed72178d1325fd4409f458David Gross                                            const RSExportVar *EV,
2079d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                            unsigned Dimension,
2080d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                            ReflectionState::Val32 AllocSize32) {
20819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!EV->isConst()) {
20820d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines    const char *FieldPackerName = "fp";
2083e2ead846c1d78a6e7108e521ffd15850bd9eed3cChih-Hung Hsieh    const std::string &VarName = EV->getName();
20840d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines    const RSExportType *ET = EV->getType();
20852e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    startFunction(AM_PublicSynchronized, false, "void", "set_" + VarName, 1,
20862e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  TypeName.c_str(), "v");
2087f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
20889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2089d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (genCreateFieldPacker(ET, FieldPackerName, AllocSize32))
20902e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genPackVarOfType(ET, "v", FieldPackerName);
2091a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines
2092a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines    if (mRSContext->getTargetAPI() < SLANG_JB_TARGET_API) {
2093a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines      // Legacy apps must use the old setVar() without Element/dim components.
2094f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
2095f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ", " << FieldPackerName << ");\n";
2096a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines    } else {
2097a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines      // We only have support for one-dimensional array reflection today,
2098a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines      // but the entry point (i.e. setVar()) takes an array of dimensions.
2099f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << "int []__dimArr = new int[1];\n";
2100657d20afa621219c1eed72178d1325fd4409f458David Gross      mOut.indent() << "__dimArr[0] = " << Dimension << ";\n";
2101f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
2102f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ", " << FieldPackerName << ", " << RS_ELEM_PREFIX
2103f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ET->getElementName() << ", __dimArr);\n";
2104a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines    }
21051ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
21062e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    endFunction();
21079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
21089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
2109462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
21102e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genGetExportVariable(const std::string &TypeName,
2111602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                            const std::string &VarName) {
21122e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, false, TypeName.c_str(), "get_" + VarName, 0);
2113462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2114f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return " << RS_EXPORT_VAR_PREFIX << VarName << ";\n";
2115462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
21162e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
211728d60bc2da19821af82d983902c3c78c078343c3Stephen Hines}
211828d60bc2da19821af82d983902c3c78c078343c3Stephen Hines
21192e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genGetFieldID(const std::string &VarName) {
212028d60bc2da19821af82d983902c3c78c078343c3Stephen Hines  // We only generate getFieldID_*() for non-Pointer (bind) types.
2121b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray  if (mRSContext->getTargetAPI() >= SLANG_JB_MR1_TARGET_API) {
21222e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    startFunction(AM_Public, false, "Script.FieldID", "getFieldID_" + VarName,
21232e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  0);
2124b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray
2125f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "return createFieldID(" << RS_EXPORT_VAR_INDEX_PREFIX
2126f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << VarName << ", null);\n";
2127b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray
21282e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    endFunction();
2129b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray  }
21309c631ff2e65a8fa766981c9683c3b255ce0a2388Shih-wei Liao}
21319c631ff2e65a8fa766981c9683c3b255ce0a2388Shih-wei Liao
21329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/******************* Methods to generate script class /end *******************/
21339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
21342e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletbool RSReflectionJava::genCreateFieldPacker(const RSExportType *ET,
2135d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                            const char *FieldPackerName,
2136d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                            ReflectionState::Val32 AllocSize32) {
2137c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet  size_t AllocSize = ET->getAllocSize();
2138d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  slangAssert(!AllocSize32.first || ((AllocSize == 0) == (AllocSize32.second == 0)));
2139d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (AllocSize > 0) {
2140d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (!mCollecting) {
2141d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      mOut.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker(";
2142d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      genConditionalVal("", false, AllocSize, AllocSize32);
2143d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      mOut << ");\n";
2144d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    }
2145d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  }
21469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  else
21479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
21489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
21499c631ff2e65a8fa766981c9683c3b255ce0a2388Shih-wei Liao}
21509c631ff2e65a8fa766981c9683c3b255ce0a2388Shih-wei Liao
21512e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genPackVarOfType(const RSExportType *ET,
2152602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                        const char *VarName,
2153602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                        const char *FieldPackerName) {
2154d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (mCollecting)
2155d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    return;
2156d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
21579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  switch (ET->getClass()) {
21582ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive:
21592ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector: {
2160f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << FieldPackerName << "."
2161f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << GetPackerAPIName(
2162f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                         static_cast<const RSExportPrimitiveType *>(ET)) << "("
2163f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << VarName << ");\n";
21642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
21652ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
21662ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPointer: {
21672ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // Must reflect as type Allocation in Java
21682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportType *PointeeType =
21692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportPointerType *>(ET)->getPointeeType();
21702e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang
2171f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    if (PointeeType->getClass() != RSExportType::ExportClassRecord) {
2172f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << FieldPackerName << ".addI32(" << VarName
2173f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ".getPtr());\n";
2174f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    } else {
2175f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << FieldPackerName << ".addI32(" << VarName
2176f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ".getAllocation().getPtr());\n";
2177f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    }
21782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
21792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
21802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassMatrix: {
2181f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << FieldPackerName << ".addMatrix(" << VarName << ");\n";
21822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
21832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
21842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray: {
21852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportConstantArrayType *ECAT =
21862ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportConstantArrayType *>(ET);
21872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
21882ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // TODO(zonr): more elegant way. Currently, we obtain the unique index
21892ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    //             variable (this method involves recursive call which means
21902ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    //             we may have more than one level loop, therefore we can't
21912ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    //             always use the same index variable name here) name given
21922ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    //             in the for-loop from counting the '.' in @VarName.
21932ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    unsigned Level = 0;
21942ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    size_t LastDotPos = 0;
21952ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::string ElementVarName(VarName);
21962ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
21972ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    while (LastDotPos != std::string::npos) {
21982ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      LastDotPos = ElementVarName.find_first_of('.', LastDotPos + 1);
21992ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      Level++;
22002e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang    }
22012ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::string IndexVarName("ct");
2202b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar    IndexVarName.append(llvm::utostr(Level));
2203462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2204f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "for (int " << IndexVarName << " = 0; " << IndexVarName
2205657d20afa621219c1eed72178d1325fd4409f458David Gross                  << " < " << ECAT->getNumElement() << "; " << IndexVarName << "++)";
2206f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.startBlock();
2207462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
22082ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    ElementVarName.append("[" + IndexVarName + "]");
22092e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genPackVarOfType(ECAT->getElementType(), ElementVarName.c_str(),
22102ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                     FieldPackerName);
2211462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2212f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.endBlock();
22132ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
22142ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
22152ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
2216d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    // Keep struct/field layout in sync with ReflectionState::declareRecord()
2217d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
22182ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportRecordType *ERT = static_cast<const RSExportRecordType *>(ET);
2219d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    const ReflectionState::Record32 Record32 = mState->getRecord32(ERT);
2220d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
2221d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    auto emitSkip = [this, &FieldPackerName](size_t At, size_t Need,
2222d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                             ReflectionState::Val32 Padding32) {
2223d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      if ((Need > At) || (Padding32.first && (Padding32.second != 0))) {
2224d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        size_t Padding = Need - At;
2225d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        mOut.indent() << FieldPackerName << ".skip(";
2226d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        if (!Padding32.first || (Padding == Padding32.second))
2227d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross          mOut << Padding;
2228d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        else {
2229d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross          genCheck64Bit(true);
2230d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross          mOut << " ? " << Padding << " : " << Padding32.second;
2231d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        }
2232d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        mOut << ");\n";
2233d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      }
2234d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    };
2235d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
22362ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // Relative pos from now on in field packer
22372ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    unsigned Pos = 0;
22382ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
2239d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    unsigned FieldNum = 0;
22402ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
22412ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                                  E = ERT->fields_end();
2242d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross         I != E; I++, FieldNum++) {
22432ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      const RSExportRecordType::Field *F = *I;
22442ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      std::string FieldName;
22452ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      size_t FieldOffset = F->getOffsetInParent();
22462ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      const RSExportType *T = F->getType();
22472ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      size_t FieldStoreSize = T->getStoreSize();
22482ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      size_t FieldAllocSize = T->getAllocSize();
22492ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
2250d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      const auto Field32PreAndPostPadding = Record32.getFieldPreAndPostPadding(FieldNum);
2251d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
22525abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes      if (VarName != nullptr)
22532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        FieldName = VarName + ("." + F->getName());
22542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      else
22552ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        FieldName = F->getName();
2256462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2257d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      emitSkip(Pos, FieldOffset, Field32PreAndPostPadding.first /* pre */);
2258462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
22592e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genPackVarOfType(F->getType(), FieldName.c_str(), FieldPackerName);
2260462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2261d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      // There is padding in the field type?
2262d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      emitSkip(FieldStoreSize, FieldAllocSize, Field32PreAndPostPadding.second /* post */);
22632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
22642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      Pos = FieldOffset + FieldAllocSize;
2265462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
22662ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
22672ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // There maybe some padding after the struct
2268d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    emitSkip(Pos, ERT->getAllocSize(), Record32.getRecordPostPadding());
22692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
22702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
22712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default: { slangAssert(false && "Unknown class of type"); }
22729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
22739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
2274462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
22752e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genAllocateVarOfType(const RSExportType *T,
2276602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                            const std::string &VarName) {
22772e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang  switch (T->getClass()) {
22782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive: {
22792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // Primitive type like int in Java has its own storage once it's declared.
22802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    //
22812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // FIXME: Should we allocate storage for RS object?
22822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // if (static_cast<const RSExportPrimitiveType *>(T)->isRSObjectType())
2283f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    //  mOut.indent() << VarName << " = new " << GetTypeName(T) << "();\n";
22842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
22852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
22862ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPointer: {
22872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // Pointer type is an instance of Allocation or a TypeClass whose value is
22882ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // expected to be assigned by programmer later in Java program. Therefore
22892ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // we don't reflect things like [VarName] = new Allocation();
2290f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << VarName << " = null;\n";
22912ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
22922ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
22932ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray: {
22942ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportConstantArrayType *ECAT =
22952ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportConstantArrayType *>(T);
22962ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportType *ElementType = ECAT->getElementType();
22972ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
2298f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << VarName << " = new " << GetTypeName(ElementType) << "["
2299657d20afa621219c1eed72178d1325fd4409f458David Gross                  << ECAT->getNumElement() << "];\n";
23002ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
23012ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // Primitive type element doesn't need allocation code.
23022ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (ElementType->getClass() != RSExportType::ExportClassPrimitive) {
2303657d20afa621219c1eed72178d1325fd4409f458David Gross      mOut.indent() << "for (int $ct = 0; $ct < " << ECAT->getNumElement()
2304f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << "; $ct++)";
2305f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.startBlock();
23062e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang
23072ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      std::string ElementVarName(VarName);
23082ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      ElementVarName.append("[$ct]");
23092e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genAllocateVarOfType(ElementType, ElementVarName);
23102e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang
2311f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.endBlock();
23122e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang    }
23132ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
23142ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
23152ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector:
23162ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassMatrix:
23172ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
2318f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << VarName << " = new " << GetTypeName(T) << "();\n";
23192ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
23202ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
23212e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang  }
23222e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang}
23232e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang
23242e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genNewItemBufferIfNull(const char *Index) {
2325f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME " == null) ";
2326f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << RS_TYPE_ITEM_BUFFER_NAME << " = new " << RS_TYPE_ITEM_CLASS_NAME
2327f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet       << "[getType().getX() /* count */];\n";
23285abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (Index != nullptr) {
2329f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME << "[" << Index
2330f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << "] == null) ";
2331f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << RS_TYPE_ITEM_BUFFER_NAME << "[" << Index << "] = new "
2332f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet         << RS_TYPE_ITEM_CLASS_NAME << "();\n";
2333f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  }
23349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
2335462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
23362e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genNewItemBufferPackerIfNull() {
2337f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " == null) ";
2338f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << RS_TYPE_ITEM_BUFFER_PACKER_NAME " = new FieldPacker("
23393a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray       <<  mItemSizeof << " * getType().getX()/* count */);\n";
2340462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2341462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
23429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/********************** Methods to generate type class  **********************/
23432e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletbool RSReflectionJava::genTypeClass(const RSExportRecordType *ERT,
2344602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                    std::string &ErrorMsg) {
2345d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mState->declareRecord(ERT);
2346d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (mCollecting)
2347d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    return true;
2348d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
2349a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines  std::string ClassName = ERT->getElementName();
23502e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  std::string superClassName = getRSPackageName();
2351f69e1e58cf65555c4be3f6c5c53f89eb044f1db5Tim Murray  superClassName += RS_TYPE_CLASS_SUPER_CLASS_NAME;
23529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
23532e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  if (!startClass(AM_Public, false, ClassName, superClassName.c_str(),
23542e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  ErrorMsg))
23559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
23569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
23574cc67fce91f43215d61b2695746eab102a3db516Stephen Hines  mGeneratedFileNames->push_back(ClassName);
23584cc67fce91f43215d61b2695746eab102a3db516Stephen Hines
2359d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mState->beginOutputClass();
2360d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
23612e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeItemClass(ERT);
23629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
23639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Declare item buffer and item buffer packer
2364f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "private " << RS_TYPE_ITEM_CLASS_NAME << " "
2365f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << RS_TYPE_ITEM_BUFFER_NAME << "[];\n";
2366f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "private FieldPacker " << RS_TYPE_ITEM_BUFFER_PACKER_NAME
2367f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << ";\n";
2368f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "private static java.lang.ref.WeakReference<Element> "
2369f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << RS_TYPE_ELEMENT_REF_NAME
2370f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << " = new java.lang.ref.WeakReference<Element>(null);\n";
23712e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
23722e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeClassConstructor(ERT);
23732e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeClassCopyToArrayLocal(ERT);
23742e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeClassCopyToArray(ERT);
23752e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeClassItemSetter(ERT);
23762e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeClassItemGetter(ERT);
23772e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeClassComponentSetter(ERT);
23782e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeClassComponentGetter(ERT);
23792e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeClassCopyAll(ERT);
238082754d87921c94e70562aa977cc92e28fc38b1d0Stephen Hines  if (!mRSContext->isCompatLib()) {
238182754d87921c94e70562aa977cc92e28fc38b1d0Stephen Hines    // Skip the resize method if we are targeting a compatibility library.
23822e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genTypeClassResize();
238382754d87921c94e70562aa977cc92e28fc38b1d0Stephen Hines  }
23849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2385d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (mState->endOutputClass())
2386d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    genCompute64Bit();
2387d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
23882e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endClass();
23899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
23902e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  resetFieldIndex();
23912e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  clearFieldIndexMap();
239266aa299de2b5e0b0c7bfae7628e29a3961247aedZonr Chang
23939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
23949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
2395462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
23962e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeItemClass(const RSExportRecordType *ERT) {
2397f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "static public class " RS_TYPE_ITEM_CLASS_NAME;
2398f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.startBlock();
23999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
24003a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray  // Sizeof should not be exposed for 64-bit; it is not accurate
24013a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray  if (mRSContext->getTargetAPI() < 21) {
24023a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray      mOut.indent() << "public static final int sizeof = " << ERT->getAllocSize()
24033a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray                    << ";\n";
24043a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray  }
24059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
24069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Member elements
2407f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << "\n";
24089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
24092ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                                FE = ERT->fields_end();
24102ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       FI != FE; FI++) {
2411f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName()
2412f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << ";\n";
24139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
24149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
24159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Constructor
2416f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << "\n";
2417f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_CLASS_NAME << "()";
2418f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.startBlock();
24199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
24209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
24212ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                                FE = ERT->fields_end();
24222ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       FI != FE; FI++) {
24239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    const RSExportRecordType::Field *F = *FI;
24242e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genAllocateVarOfType(F->getType(), F->getName());
24259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
24269e86e1926328d9ecf3cd0922e55299db901f6469Shih-wei Liao
24279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // end Constructor
2428f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.endBlock();
2429462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
24309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // end Item class
2431f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.endBlock();
2432462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2433462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
24342e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeClassConstructor(const RSExportRecordType *ERT) {
24359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const char *RenderScriptVar = "rs";
24369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
24372e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, true, "Element", "createElement", 1, "RenderScript",
24382e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                RenderScriptVar);
2439381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams
2440e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines  // TODO(all): Fix weak-refs + multi-context issue.
2441f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  // mOut.indent() << "Element e = " << RS_TYPE_ELEMENT_REF_NAME
24422968921e1cedf85360964c5a39e1ce36c66ecd09Jean-Luc Brouillet  //            << ".get();\n";
2443f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  // mOut.indent() << "if (e != null) return e;\n";
2444c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  RSReflectionJavaElementBuilder builder("eb", ERT, RenderScriptVar, &mOut,
2445d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                         mRSContext, this, mState);
2446c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  builder.generate();
2447c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
2448f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return eb.create();\n";
2449f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  // mOut.indent() << "e = eb.create();\n";
2450f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  // mOut.indent() << RS_TYPE_ELEMENT_REF_NAME
24512968921e1cedf85360964c5a39e1ce36c66ecd09Jean-Luc Brouillet  //            << " = new java.lang.ref.WeakReference<Element>(e);\n";
2452f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  // mOut.indent() << "return e;\n";
24532e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
24549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2455381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // private with element
24565abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  startFunction(AM_Private, false, nullptr, getClassName(), 1, "RenderScript",
24572e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                RenderScriptVar);
2458f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
2459f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
2460f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
24612e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2462381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams
2463381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // 1D without usage
24645abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  startFunction(AM_Public, false, nullptr, getClassName(), 2, "RenderScript",
24652e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                RenderScriptVar, "int", "count");
24669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2467f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
2468f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
2469f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
24709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Call init() in super class
2471f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "init(" << RenderScriptVar << ", count);\n";
24722e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
24739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2474381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // 1D with usage
24755abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  startFunction(AM_Public, false, nullptr, getClassName(), 3, "RenderScript",
24762e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                RenderScriptVar, "int", "count", "int", "usages");
247791fe83b56e6ffabecdb1292ff3694275ef07aed9Jason Sams
2478f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
2479f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
2480f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
248191fe83b56e6ffabecdb1292ff3694275ef07aed9Jason Sams  // Call init() in super class
2482f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "init(" << RenderScriptVar << ", count, usages);\n";
24832e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
248491fe83b56e6ffabecdb1292ff3694275ef07aed9Jason Sams
2485381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // create1D with usage
24862e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, true, getClassName().c_str(), "create1D", 3,
24872e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "RenderScript", RenderScriptVar, "int", "dimX", "int",
24882e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "usages");
2489f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << getClassName() << " obj = new " << getClassName() << "("
2490f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << RenderScriptVar << ");\n";
2491f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "obj.mAllocation = Allocation.createSized("
2492f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                   "rs, obj.mElement, dimX, usages);\n";
2493f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return obj;\n";
24942e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2495381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams
2496381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // create1D without usage
24972e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, true, getClassName().c_str(), "create1D", 2,
24982e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "RenderScript", RenderScriptVar, "int", "dimX");
2499f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return create1D(" << RenderScriptVar
2500f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << ", dimX, Allocation.USAGE_SCRIPT);\n";
25012e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2502381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams
2503381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // create2D without usage
25042e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, true, getClassName().c_str(), "create2D", 3,
25052e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "RenderScript", RenderScriptVar, "int", "dimX", "int", "dimY");
2506f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return create2D(" << RenderScriptVar
2507f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << ", dimX, dimY, Allocation.USAGE_SCRIPT);\n";
25082e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2509381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams
2510381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // create2D with usage
25112e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, true, getClassName().c_str(), "create2D", 4,
25122e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "RenderScript", RenderScriptVar, "int", "dimX", "int", "dimY",
25132e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "int", "usages");
25142e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
2515f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << getClassName() << " obj = new " << getClassName() << "("
2516f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << RenderScriptVar << ");\n";
2517f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "Type.Builder b = new Type.Builder(rs, obj.mElement);\n";
2518f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "b.setX(dimX);\n";
2519f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "b.setY(dimY);\n";
2520f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "Type t = b.create();\n";
2521f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "obj.mAllocation = Allocation.createTyped(rs, t, usages);\n";
2522f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return obj;\n";
25232e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2524381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams
2525381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // createTypeBuilder
25262e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, true, "Type.Builder", "createTypeBuilder", 1,
25272e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "RenderScript", RenderScriptVar);
2528f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "Element e = createElement(" << RenderScriptVar << ");\n";
2529f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return new Type.Builder(rs, e);\n";
25302e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2531381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams
2532381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // createCustom with usage
25332e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, true, getClassName().c_str(), "createCustom", 3,
25342e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "RenderScript", RenderScriptVar, "Type.Builder", "tb", "int",
25352e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "usages");
2536f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << getClassName() << " obj = new " << getClassName() << "("
2537f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << RenderScriptVar << ");\n";
2538f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "Type t = tb.create();\n";
2539f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (t.getElement() != obj.mElement) {\n";
2540f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "    throw new RSIllegalArgumentException("
2541f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                   "\"Type.Builder did not match expected element type.\");\n";
2542f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "}\n";
2543f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "obj.mAllocation = Allocation.createTyped(rs, t, usages);\n";
2544f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return obj;\n";
25452e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
25469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
2547462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
25482e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeClassCopyToArray(const RSExportRecordType *ERT) {
25492e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Private, false, "void", "copyToArray", 2,
25502e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                RS_TYPE_ITEM_CLASS_NAME, "i", "int", "index");
25519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
25522e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genNewItemBufferPackerIfNull();
2553f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << ".reset(index * "
25543a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray                << mItemSizeof << ");\n";
25559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2556f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "copyToArrayLocal(i, " RS_TYPE_ITEM_BUFFER_PACKER_NAME
2557f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                   ");\n";
255838eca1ad0d6bfac8f1fbf7c8360f4c18ecd205c2Alex Sakhartchouk
25592e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
256038eca1ad0d6bfac8f1fbf7c8360f4c18ecd205c2Alex Sakhartchouk}
256138eca1ad0d6bfac8f1fbf7c8360f4c18ecd205c2Alex Sakhartchouk
2562602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouilletvoid
25632e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc BrouilletRSReflectionJava::genTypeClassCopyToArrayLocal(const RSExportRecordType *ERT) {
25642e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Private, false, "void", "copyToArrayLocal", 2,
25652e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                RS_TYPE_ITEM_CLASS_NAME, "i", "FieldPacker", "fp");
256638eca1ad0d6bfac8f1fbf7c8360f4c18ecd205c2Alex Sakhartchouk
25672e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genPackVarOfType(ERT, "i", "fp");
25689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
25692e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
25709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
2571462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
25722e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeClassItemSetter(const RSExportRecordType *ERT) {
25732e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_PublicSynchronized, false, "void", "set", 3,
25742e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                RS_TYPE_ITEM_CLASS_NAME, "i", "int", "index", "boolean",
25752e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "copyNow");
25765abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  genNewItemBufferIfNull(nullptr);
2577f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << "[index] = i;\n";
25789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2579f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (copyNow) ";
2580f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.startBlock();
25819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2582f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "copyToArray(i, index);\n";
25833a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray  mOut.indent() << "FieldPacker fp = new FieldPacker(" << mItemSizeof << ");\n";
2584f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "copyToArrayLocal(i, fp);\n";
2585f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "mAllocation.setFromFieldPacker(index, fp);\n";
25869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
25879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // End of if (copyNow)
2588f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.endBlock();
25899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
25902e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
25919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
2592462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
25932e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeClassItemGetter(const RSExportRecordType *ERT) {
25942e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_PublicSynchronized, false, RS_TYPE_ITEM_CLASS_NAME, "get", 1,
25952e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "int", "index");
2596f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME
2597f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << " == null) return null;\n";
2598f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return " << RS_TYPE_ITEM_BUFFER_NAME << "[index];\n";
25992e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2600462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2601462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2602602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouilletvoid
26032e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc BrouilletRSReflectionJava::genTypeClassComponentSetter(const RSExportRecordType *ERT) {
2604d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  const ReflectionState::Record32 Record32 = mState->getRecord32(ERT);
2605d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
2606d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  unsigned FieldNum = 0;
26079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
2608602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                                FE = ERT->fields_end();
2609d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross       FI != FE; FI++, FieldNum++) {
26109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    const RSExportRecordType::Field *F = *FI;
26119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    size_t FieldOffset = F->getOffsetInParent();
2612c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet    size_t FieldStoreSize = F->getType()->getStoreSize();
2613d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    std::pair<unsigned, unsigned> FieldIndex = getFieldIndex(F);
2614d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
2615d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    const auto Field32OffsetAndStoreSize = Record32.getFieldOffsetAndStoreSize(FieldNum);
26169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
26172e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    startFunction(AM_PublicSynchronized, false, "void", "set_" + F->getName(),
26182e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  3, "int", "index", GetTypeName(F->getType()).c_str(), "v",
26192e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  "boolean", "copyNow");
26202e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genNewItemBufferPackerIfNull();
26212e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genNewItemBufferIfNull("index");
2622f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << "[index]." << F->getName()
2623f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << " = v;\n";
2624462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2625f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "if (copyNow) ";
2626f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.startBlock();
26272dd42ffb0679851777ec4733681816d399d5f7d3Shih-wei Liao
2628d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << ".reset(index * "
2629d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                  << mItemSizeof;
2630d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    genConditionalVal(" + ", true, FieldOffset, Field32OffsetAndStoreSize.first /* offset */);
2631d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mOut << ");\n";
2632d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
26332e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genPackVarOfType(F->getType(), "v", RS_TYPE_ITEM_BUFFER_PACKER_NAME);
2634462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2635d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mOut.indent() << "FieldPacker fp = new FieldPacker(";
2636d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    genConditionalVal("", false, FieldStoreSize, Field32OffsetAndStoreSize.second /* size */);
2637d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mOut << ");\n";
2638d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
26392e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genPackVarOfType(F->getType(), "v", "fp");
2640d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mOut.indent() << "mAllocation.setFromFieldPacker(index, ";
2641d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    genConditionalVal("", false, FieldIndex.first,
2642d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                      ReflectionState::Val32(Field32OffsetAndStoreSize.first.first, FieldIndex.second));
2643d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mOut << ", fp);\n";
2644462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
26459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // End of if (copyNow)
2646f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.endBlock();
2647462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
26482e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    endFunction();
26499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
26509c631ff2e65a8fa766981c9683c3b255ce0a2388Shih-wei Liao}
26519c631ff2e65a8fa766981c9683c3b255ce0a2388Shih-wei Liao
2652602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouilletvoid
26532e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc BrouilletRSReflectionJava::genTypeClassComponentGetter(const RSExportRecordType *ERT) {
26549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
2655602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                                FE = ERT->fields_end();
2656602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet       FI != FE; FI++) {
26579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    const RSExportRecordType::Field *F = *FI;
26582e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    startFunction(AM_PublicSynchronized, false,
26592e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  GetTypeName(F->getType()).c_str(), "get_" + F->getName(), 1,
26602e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  "int", "index");
2661f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "if (" RS_TYPE_ITEM_BUFFER_NAME << " == null) return "
2662f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << GetTypeNullValue(F->getType()) << ";\n";
2663f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "return " RS_TYPE_ITEM_BUFFER_NAME << "[index]."
2664f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << F->getName() << ";\n";
26652e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    endFunction();
26669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
26679c631ff2e65a8fa766981c9683c3b255ce0a2388Shih-wei Liao}
26689b1f50b1cab0687f2f218a924e4ff90184aebe0aShih-wei Liao
26692e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeClassCopyAll(const RSExportRecordType *ERT) {
26702e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_PublicSynchronized, false, "void", "copyAll", 0);
2671462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2672f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "for (int ct = 0; ct < " << RS_TYPE_ITEM_BUFFER_NAME
2673f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << ".length; ct++)"
2674f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << " copyToArray(" << RS_TYPE_ITEM_BUFFER_NAME
2675f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << "[ct], ct);\n";
2676f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "mAllocation.setFromFieldPacker(0, "
2677f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << RS_TYPE_ITEM_BUFFER_PACKER_NAME ");\n";
2678462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
26792e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2680462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2681462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
26822e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeClassResize() {
26832e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_PublicSynchronized, false, "void", "resize", 1, "int",
26842e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "newSize");
26852e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
2686f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (mItemArray != null) ";
2687f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.startBlock();
2688f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "int oldSize = mItemArray.length;\n";
2689f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "int copySize = Math.min(oldSize, newSize);\n";
2690f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (newSize == oldSize) return;\n";
2691f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "Item ni[] = new Item[newSize];\n";
2692f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "System.arraycopy(mItemArray, 0, ni, 0, copySize);\n";
2693f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "mItemArray = ni;\n";
2694f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.endBlock();
2695f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "mAllocation.resize(newSize);\n";
2696f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
2697f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (" RS_TYPE_ITEM_BUFFER_PACKER_NAME
2698f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                   " != null) " RS_TYPE_ITEM_BUFFER_PACKER_NAME " = "
26993a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray                   "new FieldPacker(" << mItemSizeof << " * getType().getX()/* count */);\n";
27002e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
27012e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2702d42a429f42fd6f272188af64f412cd604f02b365Zonr Chang}
2703d42a429f42fd6f272188af64f412cd604f02b365Zonr Chang
27049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/******************** Methods to generate type class /end ********************/
2705462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
27069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/********** Methods to create Element in Java of given record type ***********/
2707c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
2708c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc BrouilletRSReflectionJavaElementBuilder::RSReflectionJavaElementBuilder(
2709c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    const char *ElementBuilderName, const RSExportRecordType *ERT,
2710c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    const char *RenderScriptVar, GeneratedFile *Out, const RSContext *RSContext,
2711d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    RSReflectionJava *Reflection, ReflectionState *RState)
2712c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    : mElementBuilderName(ElementBuilderName), mERT(ERT),
2713c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      mRenderScriptVar(RenderScriptVar), mOut(Out), mPaddingFieldIndex(1),
2714d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      mRSContext(RSContext), mReflection(Reflection), mState(RState) {
2715c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  if (mRSContext->getTargetAPI() < SLANG_ICS_TARGET_API) {
2716c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    mPaddingPrefix = "#padding_";
2717c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  } else {
2718c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    mPaddingPrefix = "#rs_padding_";
2719c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  }
2720c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet}
2721c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
2722c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouilletvoid RSReflectionJavaElementBuilder::generate() {
2723c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  mOut->indent() << "Element.Builder " << mElementBuilderName
2724c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                 << " = new Element.Builder(" << mRenderScriptVar << ");\n";
2725c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  genAddElement(mERT, "", /* ArraySize = */ 0);
2726462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2727462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2728c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouilletvoid RSReflectionJavaElementBuilder::genAddElement(const RSExportType *ET,
2729c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                                                   const std::string &VarName,
2730c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                                                   unsigned ArraySize) {
273147aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines  std::string ElementConstruct = GetBuiltinElementConstruct(ET);
27329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
273347aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines  if (ElementConstruct != "") {
2734c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    genAddStatementStart();
2735c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    *mOut << ElementConstruct << "(" << mRenderScriptVar << ")";
2736c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    genAddStatementEnd(VarName, ArraySize);
27379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  } else {
2738c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
2739c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    switch (ET->getClass()) {
2740c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RSExportType::ExportClassPrimitive: {
27419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const RSExportPrimitiveType *EPT =
27422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet          static_cast<const RSExportPrimitiveType *>(ET);
274347aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines      const char *DataTypeName =
274447aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines          RSExportPrimitiveType::getRSReflectionType(EPT)->rs_type;
2745c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      genAddStatementStart();
2746c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      *mOut << "Element.createUser(" << mRenderScriptVar
2747c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet            << ", Element.DataType." << DataTypeName << ")";
2748c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      genAddStatementEnd(VarName, ArraySize);
2749c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      break;
2750c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    }
2751c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RSExportType::ExportClassVector: {
2752c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      const RSExportVectorType *EVT =
2753c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet          static_cast<const RSExportVectorType *>(ET);
2754c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      const char *DataTypeName =
2755c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet          RSExportPrimitiveType::getRSReflectionType(EVT)->rs_type;
2756c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      genAddStatementStart();
2757c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      *mOut << "Element.createVector(" << mRenderScriptVar
2758c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet            << ", Element.DataType." << DataTypeName << ", "
2759c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet            << EVT->getNumElement() << ")";
2760c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      genAddStatementEnd(VarName, ArraySize);
2761c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      break;
2762c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    }
2763c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RSExportType::ExportClassPointer:
27649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Pointer type variable should be resolved in
27659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // GetBuiltinElementConstruct()
27666e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert(false && "??");
2767c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      break;
2768c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RSExportType::ExportClassMatrix:
276992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang      // Matrix type variable should be resolved
277092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang      // in GetBuiltinElementConstruct()
27716e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert(false && "??");
2772c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      break;
2773c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RSExportType::ExportClassConstantArray: {
27742e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang      const RSExportConstantArrayType *ECAT =
27752e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang          static_cast<const RSExportConstantArrayType *>(ET);
27762e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang
277789273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang      const RSExportType *ElementType = ECAT->getElementType();
277889273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang      if (ElementType->getClass() != RSExportType::ExportClassRecord) {
2779657d20afa621219c1eed72178d1325fd4409f458David Gross        genAddElement(ECAT->getElementType(), VarName, ECAT->getNumElement());
278089273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang      } else {
2781f3edb0046f0c1389f1318f8e7d4ea3ab9453d599David Gross        slangAssert((ArraySize == 0) && "Cannot reflect multidimensional array types");
2782657d20afa621219c1eed72178d1325fd4409f458David Gross        ArraySize = ECAT->getNumElement();
2783c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        genAddStatementStart();
2784f3edb0046f0c1389f1318f8e7d4ea3ab9453d599David Gross        *mOut << ElementType->getElementName() << ".createElement(" << mRenderScriptVar << ")";
2785c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        genAddStatementEnd(VarName, ArraySize);
278689273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang      }
2787c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      break;
2788c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    }
2789c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RSExportType::ExportClassRecord: {
27909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Simalar to case of RSExportType::ExportClassRecord in genPackVarOfType.
27919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      //
27926315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      // TODO(zonr): Generalize these two function such that there's no
27936315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      //             duplicated codes.
2794d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
2795d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      // Keep struct/field layout in sync with ReflectionState::declareRecord()
2796d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
27979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const RSExportRecordType *ERT =
27982ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet          static_cast<const RSExportRecordType *>(ET);
2799d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      const ReflectionState::Record32 Record32 = mState->getRecord32(ERT);
2800d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
28012ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      int Pos = 0; // relative pos from now on
28029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2803d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      unsigned FieldNum = 0;
28049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
28052ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                                    E = ERT->fields_end();
2806d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross           I != E; I++, FieldNum++) {
28079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const RSExportRecordType::Field *F = *I;
2808d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        size_t FieldOffset = F->getOffsetInParent();
2809c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet        const RSExportType *T = F->getType();
2810d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        size_t FieldStoreSize = T->getStoreSize();
2811d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        size_t FieldAllocSize = T->getAllocSize();
2812d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
2813d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        const auto Field32PreAndPostPadding = Record32.getFieldPreAndPostPadding(FieldNum);
28149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2815c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        std::string FieldName;
28169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (!VarName.empty())
28179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldName = VarName + "." + F->getName();
28189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        else
28199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldName = F->getName();
28209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
28219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Alignment
2822d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross        genAddPadding(FieldOffset - Pos, Field32PreAndPostPadding.first /* pre */);
28239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
28249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // eb.add(...)
2825c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        mReflection->addFieldIndexMapping(F);
282689273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang        if (F->getType()->getClass() != RSExportType::ExportClassRecord) {
2827c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet          genAddElement(F->getType(), FieldName, 0);
282889273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang        } else {
2829c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet          genAddStatementStart();
2830f3edb0046f0c1389f1318f8e7d4ea3ab9453d599David Gross          *mOut << F->getType()->getElementName() << ".createElement(" << mRenderScriptVar << ")";
2831c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet          genAddStatementEnd(FieldName, ArraySize);
283289273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang        }
28339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2834a9ae5ae8866d937a99601d24a922c8f3f4223f59Stephen Hines        if (mRSContext->getTargetAPI() < SLANG_ICS_TARGET_API) {
2835a9ae5ae8866d937a99601d24a922c8f3f4223f59Stephen Hines          // There is padding within the field type. This is only necessary
2836a9ae5ae8866d937a99601d24a922c8f3f4223f59Stephen Hines          // for HC-targeted APIs.
2837d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross          genAddPadding(FieldAllocSize - FieldStoreSize, Field32PreAndPostPadding.second /* post */);
2838a9ae5ae8866d937a99601d24a922c8f3f4223f59Stephen Hines        }
28399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
28409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        Pos = FieldOffset + FieldAllocSize;
28419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
2842bd49c8ff5a35befb413de3b6d7989d257b54f057Shih-wei Liao
28439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // There maybe some padding after the struct
2844c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet      size_t RecordAllocSize = ERT->getAllocSize();
2845d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      genAddPadding(RecordAllocSize - Pos, Record32.getRecordPostPadding());
2846c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      break;
2847c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    }
2848c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    default:
28496e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert(false && "Unknown class of type");
2850c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      break;
2851b1a28e752571e744444377c89e5c256b4332dc58Shih-wei Liao    }
28529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2853462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2854462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2855d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Grossvoid RSReflectionJavaElementBuilder::genAddPadding(int PaddingSize, unsigned Which) {
28569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  while (PaddingSize > 0) {
28572e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    const std::string &VarName = createPaddingField();
2858c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    genAddStatementStart();
28599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (PaddingSize >= 4) {
2860c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      *mOut << "Element.U32(" << mRenderScriptVar << ")";
28619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      PaddingSize -= 4;
28629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    } else if (PaddingSize >= 2) {
2863c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      *mOut << "Element.U16(" << mRenderScriptVar << ")";
28649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      PaddingSize -= 2;
28659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    } else if (PaddingSize >= 1) {
2866c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      *mOut << "Element.U8(" << mRenderScriptVar << ")";
28679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      PaddingSize -= 1;
2868462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2869d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    genAddStatementEnd(VarName, 0, Which);
28709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2871462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2872462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2873d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Grossvoid RSReflectionJavaElementBuilder::genAddPadding(int PaddingSize,
2874d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                                   ReflectionState::Val32 Field32PaddingSize) {
2875d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (!Field32PaddingSize.first || (PaddingSize == Field32PaddingSize.second)) {
2876d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    // Either we're ignoring the 32-bit case, or 32-bit and 64-bit
2877d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    // padding are the same.
2878d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    genAddPadding(PaddingSize, RSReflectionJava::FieldIndex | RSReflectionJava::Field32Index);
2879d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    return;
2880d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  }
2881d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
2882d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // We cannot ignore the 32-bit case, and 32-bit and 64-bit padding differ.
2883d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
2884d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if ((PaddingSize == 0) != (Field32PaddingSize.second == 0)) {
2885d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    // Only pad one of the two cases.
2886d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
2887d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mOut->indent() << "if (";
2888d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (PaddingSize == 0)
2889d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      *mOut << '!';
2890d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    genCheck64Bit(PaddingSize == 0);
2891d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    *mOut << ')';
2892d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
2893d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mOut->startBlock();
2894d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    if (PaddingSize != 0)
2895d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      genAddPadding(PaddingSize, RSReflectionJava::FieldIndex);
2896d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    else
2897d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross      genAddPadding(Field32PaddingSize.second, RSReflectionJava::Field32Index);
2898d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mOut->endBlock();
2899d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    return;
2900d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  }
2901d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
2902d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // Pad both of the two cases, differently.
2903d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut->indent() << "if (";
2904d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  genCheck64Bit(false);
2905d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  *mOut << ')';
2906d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut->startBlock();
2907d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  genAddPadding(PaddingSize, RSReflectionJava::FieldIndex);
2908d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut->endBlock();
2909d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut->indent() << "else";
2910d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut->startBlock();
2911d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  genAddPadding(Field32PaddingSize.second, RSReflectionJava::Field32Index);
2912d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mOut->endBlock();
2913d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross}
2914d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
2915c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouilletvoid RSReflectionJavaElementBuilder::genAddStatementStart() {
2916c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  mOut->indent() << mElementBuilderName << ".add(";
2917c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet}
2918c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
2919c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouilletvoid
2920c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc BrouilletRSReflectionJavaElementBuilder::genAddStatementEnd(const std::string &VarName,
2921d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                                   unsigned ArraySize,
2922d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross                                                   unsigned Which) {
2923c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  *mOut << ", \"" << VarName << "\"";
2924c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  if (ArraySize > 0) {
2925c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    *mOut << ", " << ArraySize;
2926c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  }
2927c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  *mOut << ");\n";
2928c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  // TODO Review incFieldIndex.  It's probably better to assign the numbers at
2929c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  // the start rather
2930c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  // than as we're generating the code.
2931d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mReflection->incFieldIndex(Which);
2932c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet}
2933c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
29349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/******** Methods to create Element in Java of given record type /end ********/
2935462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
293659f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouilletbool RSReflectionJava::reflect() {
2937d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // Note that we may issue declareRecord() in many places during the
2938d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // reflection process.
2939d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mState->beginRecords();
2940d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
294159f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet  std::string ErrorMsg;
294259f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet  if (!genScriptClass(mScriptClassName, ErrorMsg)) {
294359f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet    std::cerr << "Failed to generate class " << mScriptClassName << " ("
29442e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet              << ErrorMsg << ")\n";
29452e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    return false;
29462e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  }
29479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
29482e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  // class ScriptField_<TypeName>
29492e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  for (RSContext::const_export_type_iterator
29502e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet           TI = mRSContext->export_types_begin(),
29512e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet           TE = mRSContext->export_types_end();
29522e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet       TI != TE; TI++) {
29532e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    const RSExportType *ET = TI->getValue();
29542e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
29552e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    if (ET->getClass() == RSExportType::ExportClassRecord) {
29562e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      const RSExportRecordType *ERT =
29572e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet          static_cast<const RSExportRecordType *>(ET);
29582e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
29592e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      if (!ERT->isArtificial() && !genTypeClass(ERT, ErrorMsg)) {
29602e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        std::cerr << "Failed to generate type class for struct '"
29612e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  << ERT->getName() << "' (" << ErrorMsg << ")\n";
29622e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        return false;
29639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
2964462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
29659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2966462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2967d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  mState->endRecords();
2968d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross
29699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
2970462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2971462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
29722e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletconst char *RSReflectionJava::AccessModifierStr(AccessModifier AM) {
29739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  switch (AM) {
29742ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case AM_Public:
29752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return "public";
29762ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
29772ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case AM_Protected:
29782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return "protected";
29792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
29802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case AM_Private:
29812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return "private";
29822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
29832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case AM_PublicSynchronized:
29842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return "public synchronized";
29852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
29862ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default:
29872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return "";
29882ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
29899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2990462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2991462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
29922e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletbool RSReflectionJava::startClass(AccessModifier AM, bool IsStatic,
29932e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                  const std::string &ClassName,
29942e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                  const char *SuperClassName,
29952e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                  std::string &ErrorMsg) {
29968c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang  // Open file for class
2997f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  std::string FileName = ClassName + ".java";
299859f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet  if (!mOut.startFile(mOutputDirectory, FileName, mRSSourceFileName,
2999fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines                      mRSContext->getLicenseNote(), true,
3000fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines                      mRSContext->getVerbose())) {
30018c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang    return false;
3002f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  }
30039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
30049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Package
3005f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  if (!mPackageName.empty()) {
3006f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << "package " << mPackageName << ";\n";
3007f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  }
3008f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << "\n";
30099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
30109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Imports
3011d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  //
3012d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // The first few imports are only needed for divergent classes, but
3013d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // at this point we don't know whether we are emitting a divergent
3014d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // class.
3015d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  //
3016d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  if (!mRSContext->isCompatLib()) {
3017d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mOut << "import android.os.Build;\n";
3018d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mOut << "import android.os.Process;\n";
3019d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross    mOut << "import java.lang.reflect.Field;\n";
3020d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  }
3021d80e58b259c2febc4907aed4aca9d88d43bdd1a1David Gross  // (End of imports needed for divergent classes.)
3022f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << "import " << mRSPackageName << ".*;\n";
302344d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines  if (getEmbedBitcodeInJava()) {
3024f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << "import " << mPackageName << "."
302544d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines          << RSSlangReflectUtils::JavaBitcodeClassNameFromRSFileName(
302659f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                 mRSSourceFileName.c_str()) << ";\n";
302744d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines  } else {
3028f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << "import android.content.res.Resources;\n";
302944d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines  }
3030f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << "\n";
30319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
30329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // All reflected classes should be annotated as hidden, so that they won't
30339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // be exposed in SDK.
3034f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << "/**\n";
3035f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << " * @hide\n";
3036f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << " */\n";
30379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3038f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class "
3039f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet       << ClassName;
30405abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (SuperClassName != nullptr)
3041f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << " extends " << SuperClassName;
30429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3043f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.startBlock();
30449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
30459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mClassName = ClassName;
30469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
30479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
3048462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
3049462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
30502e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::endClass() {
3051f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.endBlock();
3052f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.closeFile();
30539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  clear();
3054462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
3055462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
30562e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::startTypeClass(const std::string &ClassName) {
3057f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "public static class " << ClassName;
3058f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.startBlock();
3059462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
3060462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3061f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouilletvoid RSReflectionJava::endTypeClass() { mOut.endBlock(); }
3062462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
30632e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::startFunction(AccessModifier AM, bool IsStatic,
30642e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                     const char *ReturnType,
30652e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                     const std::string &FunctionName, int Argc,
30662e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                     ...) {
30679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  ArgTy Args;
30689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  va_list vl;
30699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  va_start(vl, Argc);
3070462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
30716315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  for (int i = 0; i < Argc; i++) {
30722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const char *ArgType = va_arg(vl, const char *);
30732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const char *ArgName = va_arg(vl, const char *);
3074462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
30756315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    Args.push_back(std::make_pair(ArgType, ArgName));
30769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
30779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  va_end(vl);
3078462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
30799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  startFunction(AM, IsStatic, ReturnType, FunctionName, Args);
3080462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
3081462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
30822e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::startFunction(AccessModifier AM, bool IsStatic,
30832e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                     const char *ReturnType,
30842e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                     const std::string &FunctionName,
30852e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                     const ArgTy &Args) {
3086f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ")
3087f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << ((ReturnType) ? ReturnType : "") << " " << FunctionName
3088f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << "(";
30899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
30909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  bool FirstArg = true;
30912ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  for (ArgTy::const_iterator I = Args.begin(), E = Args.end(); I != E; I++) {
30929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (!FirstArg)
3093f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut << ", ";
30949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    else
30959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      FirstArg = false;
3096462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3097f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << I->first << " " << I->second;
30989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
3099462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3100f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << ")";
3101f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.startBlock();
3102462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
3103462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3104f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouilletvoid RSReflectionJava::endFunction() { mOut.endBlock(); }
3105e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
31062e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletbool RSReflectionJava::addTypeNameForElement(const std::string &TypeName) {
31071f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  if (mTypesToCheck.find(TypeName) == mTypesToCheck.end()) {
31081f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    mTypesToCheck.insert(TypeName);
31091f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    return true;
31101f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  } else {
31111f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    return false;
31121f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  }
31131f6c331d622ac645ab68a016aa4c577998547373Stephen Hines}
31141f6c331d622ac645ab68a016aa4c577998547373Stephen Hines
31152e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletbool RSReflectionJava::addTypeNameForFieldPacker(const std::string &TypeName) {
31161f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  if (mFieldPackerTypes.find(TypeName) == mFieldPackerTypes.end()) {
31171f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    mFieldPackerTypes.insert(TypeName);
31181f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    return true;
31191f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  } else {
31201f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    return false;
31211f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  }
31221f6c331d622ac645ab68a016aa4c577998547373Stephen Hines}
31231f6c331d622ac645ab68a016aa4c577998547373Stephen Hines
31242ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet} // namespace slang
3125