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"
394cc499d6e5ec602309501873449c938af61170b2Stephen Hines#include "slang_version.h"
406315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
412ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_SCRIPT_CLASS_NAME_PREFIX "ScriptC_"
429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#define RS_SCRIPT_CLASS_SUPER_CLASS_NAME "ScriptC"
43462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
442ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_TYPE_CLASS_SUPER_CLASS_NAME ".Script.FieldBase"
45462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
462ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_TYPE_ITEM_CLASS_NAME "Item"
47462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
483a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray#define RS_TYPE_ITEM_SIZEOF_LEGACY "Item.sizeof"
493a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray#define RS_TYPE_ITEM_SIZEOF_CURRENT "mElement.getBytesSize()"
503a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray
512ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_TYPE_ITEM_BUFFER_NAME "mItemArray"
522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_TYPE_ITEM_BUFFER_PACKER_NAME "mIOBuffer"
532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_TYPE_ELEMENT_REF_NAME "mElementCache"
54462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
552ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_EXPORT_VAR_INDEX_PREFIX "mExportVarIdx_"
562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_EXPORT_VAR_PREFIX "mExportVar_"
572ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_EXPORT_VAR_ELEM_PREFIX "mExportVarElem_"
582ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_EXPORT_VAR_DIM_PREFIX "mExportVarDim_"
592ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_EXPORT_VAR_CONST_PREFIX "const_"
60462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
612ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_ELEM_PREFIX "__"
62a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines
632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_FP_PREFIX "__rs_fp_"
641f6c331d622ac645ab68a016aa4c577998547373Stephen Hines
652ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_RESOURCE_NAME "__rs_resource_name"
66d2936939ec10879e25746322db60071f79f28c1bStephen Hines
672ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_EXPORT_FUNC_INDEX_PREFIX "mExportFuncIdx_"
682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_EXPORT_FOREACH_INDEX_PREFIX "mExportForEachIdx_"
697682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala#define RS_EXPORT_REDUCE_INDEX_PREFIX "mExportReduceIdx_"
70462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_EXPORT_VAR_ALLOCATION_PREFIX "mAlloction_"
729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#define RS_EXPORT_VAR_DATA_STORAGE_PREFIX "mData_"
73462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
747682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala#define SAVED_RS_REFERENCE "mRSLocal"
757682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
76e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
77462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
78c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouilletclass RSReflectionJavaElementBuilder {
79c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouilletpublic:
80c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  RSReflectionJavaElementBuilder(const char *ElementBuilderName,
81c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                                 const RSExportRecordType *ERT,
82c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                                 const char *RenderScriptVar,
83c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                                 GeneratedFile *Out, const RSContext *RSContext,
84c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                                 RSReflectionJava *Reflection);
85c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  void generate();
86c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
87c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouilletprivate:
88c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  void genAddElement(const RSExportType *ET, const std::string &VarName,
89c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                     unsigned ArraySize);
90c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  void genAddStatementStart();
91c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  void genAddStatementEnd(const std::string &VarName, unsigned ArraySize);
92c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  void genAddPadding(int PaddingSize);
93c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  // TODO Will remove later due to field name information is not necessary for
94c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  // C-reflect-to-Java
95c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  std::string createPaddingField() {
96c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    return mPaddingPrefix + llvm::itostr(mPaddingFieldIndex++);
97c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  }
98c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
99c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  const char *mElementBuilderName;
100c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  const RSExportRecordType *mERT;
101c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  const char *mRenderScriptVar;
102c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  GeneratedFile *mOut;
103c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  std::string mPaddingPrefix;
104c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  int mPaddingFieldIndex;
105c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  const RSContext *mRSContext;
106c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  RSReflectionJava *mReflection;
107c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet};
108c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
10992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Changstatic const char *GetMatrixTypeName(const RSExportMatrixType *EMT) {
1102ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  static const char *MatrixTypeJavaNameMap[] = {/* 2x2 */ "Matrix2f",
1112ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                                /* 3x3 */ "Matrix3f",
1122ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                                /* 4x4 */ "Matrix4f",
11392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang  };
11492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang  unsigned Dim = EMT->getDim();
11592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
1162ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  if ((Dim - 2) < (sizeof(MatrixTypeJavaNameMap) / sizeof(const char *)))
1172ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return MatrixTypeJavaNameMap[EMT->getDim() - 2];
11892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
1196e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert(false && "GetMatrixTypeName : Unsupported matrix dimension");
1205abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  return nullptr;
12192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang}
12292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
1236e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hinesstatic const char *GetVectorAccessor(unsigned Index) {
1242ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  static const char *VectorAccessorMap[] = {/* 0 */ "x",
1252ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                            /* 1 */ "y",
1262ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                            /* 2 */ "z",
1272ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                            /* 3 */ "w",
1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  };
129324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao
1302ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  slangAssert((Index < (sizeof(VectorAccessorMap) / sizeof(const char *))) &&
1316e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines              "Out-of-bound index to access vector member");
132324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao
1339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return VectorAccessorMap[Index];
134324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao}
135324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao
1369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaostatic const char *GetPackerAPIName(const RSExportPrimitiveType *EPT) {
1376315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  static const char *PrimitiveTypePackerAPINameMap[] = {
1382a7ec01e812624ff7685d7de5528e8fc1a4acc9ePirama Arumuga Nainar      "addI16",     // DataTypeFloat16
1392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addF32",     // DataTypeFloat32
1402ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addF64",     // DataTypeFloat64
1412ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addI8",      // DataTypeSigned8
1422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addI16",     // DataTypeSigned16
1432ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addI32",     // DataTypeSigned32
1442ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addI64",     // DataTypeSigned64
1452ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addU8",      // DataTypeUnsigned8
1462ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addU16",     // DataTypeUnsigned16
1472ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addU32",     // DataTypeUnsigned32
1482ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addU64",     // DataTypeUnsigned64
1492ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addBoolean", // DataTypeBoolean
1502ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addU16",     // DataTypeUnsigned565
1512ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addU16",     // DataTypeUnsigned5551
1522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addU16",     // DataTypeUnsigned4444
1532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addMatrix",  // DataTypeRSMatrix2x2
1542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addMatrix",  // DataTypeRSMatrix3x3
1552ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addMatrix",  // DataTypeRSMatrix4x4
1562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSElement
1572ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSType
1582ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSAllocation
1592ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSSampler
1602ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSScript
1612ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSMesh
1622ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSPath
1632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSProgramFragment
1642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSProgramVertex
1652ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSProgramRaster
1662ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSProgramStore
1672ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "addObj",     // DataTypeRSFont
1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  };
1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  unsigned TypeId = EPT->getType();
1709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  if (TypeId < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char *)))
1722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return PrimitiveTypePackerAPINameMap[EPT->getType()];
1739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1746e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert(false && "GetPackerAPIName : Unknown primitive data type");
1755abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  return nullptr;
176462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
177462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
178277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Grossnamespace {
179277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
180277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Grossenum {
181277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  TypeNameWithConstantArrayBrackets = 0x01,
182277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  TypeNameWithRecordElementName     = 0x02,
183277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  TypeNameC                         = 0x04, // else Java
184277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  TypeNameDefault                   = TypeNameWithConstantArrayBrackets|TypeNameWithRecordElementName
185277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross};
186277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
187277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Grossstd::string GetTypeName(const RSExportType *ET, unsigned Style = TypeNameDefault) {
1889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  switch (ET->getClass()) {
1892ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive: {
190277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const auto ReflectionType =
191277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        RSExportPrimitiveType::getRSReflectionType(static_cast<const RSExportPrimitiveType *>(ET));
192277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    return (Style & TypeNameC ? ReflectionType->s_name : ReflectionType->java_name);
1932ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
1942ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPointer: {
195277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    slangAssert(!(Style & TypeNameC) &&
196277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                "No need to support C type names for pointer types yet");
1972ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportType *PointeeType =
1982ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportPointerType *>(ET)->getPointeeType();
1999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2002ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (PointeeType->getClass() != RSExportType::ExportClassRecord)
2012ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      return "Allocation";
2022ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    else
2032ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      return PointeeType->getElementName();
2042ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
2052ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector: {
2062ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportVectorType *EVT = static_cast<const RSExportVectorType *>(ET);
207277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const auto ReflectionType = EVT->getRSReflectionType(EVT);
2082ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::stringstream VecName;
209277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    VecName << (Style & TypeNameC ? ReflectionType->s_name : ReflectionType->rs_java_vector_prefix)
2102ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            << EVT->getNumElement();
2112ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return VecName.str();
2122ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
2132ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassMatrix: {
214277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    slangAssert(!(Style & TypeNameC) &&
215277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                "No need to support C type names for matrix types yet");
2162ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return GetMatrixTypeName(static_cast<const RSExportMatrixType *>(ET));
2172ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
2182ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray: {
2192ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportConstantArrayType *CAT =
2202ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportConstantArrayType *>(ET);
221277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    std::string ElementTypeName = GetTypeName(CAT->getElementType(), Style);
222277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (Style & TypeNameWithConstantArrayBrackets) {
223277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      slangAssert(!(Style & TypeNameC) &&
224277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                  "No need to support C type names for array types with brackets yet");
2252ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      ElementTypeName.append("[]");
2269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
2272ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return ElementTypeName;
2282ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
2292ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
230277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    slangAssert(!(Style & TypeNameC) &&
231277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                "No need to support C type names for record types yet");
232277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (Style & TypeNameWithRecordElementName)
233277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      return ET->getElementName() + "." RS_TYPE_ITEM_CLASS_NAME;
234277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    else
235277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      return ET->getName();
2362ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
2372ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default: { slangAssert(false && "Unknown class of type"); }
2389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
239462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return "";
241462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
242462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2431c6bf88e098c767c3cd445f2c2514f0598d91501David Grossstd::string GetReduceResultTypeName(const RSExportType *ET) {
244277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  switch (ET->getClass()) {
245277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    case RSExportType::ExportClassConstantArray: {
246277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      const RSExportConstantArrayType *const CAT = static_cast<const RSExportConstantArrayType *>(ET);
247277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      return "resultArray" + std::to_string(CAT->getNumElement()) + "_" +
248277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross          GetTypeName(CAT->getElementType(),
249277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                      (TypeNameDefault & ~TypeNameWithRecordElementName) | TypeNameC);
250277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
251277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    case RSExportType::ExportClassRecord:
252277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      return "resultStruct_" + GetTypeName(ET,
253277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                                           (TypeNameDefault & ~TypeNameWithRecordElementName) | TypeNameC);
254277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    default:
255277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      return "result_" + GetTypeName(ET, TypeNameDefault | TypeNameC);
256277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
257277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
258277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
2591c6bf88e098c767c3cd445f2c2514f0598d91501David Grossstd::string GetReduceResultTypeName(const RSExportReduce *ER) {
2601c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  return GetReduceResultTypeName(ER->getResultType());
261277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
262277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
263277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross} // end anonymous namespace
264277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
265cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liaostatic const char *GetTypeNullValue(const RSExportType *ET) {
266cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao  switch (ET->getClass()) {
2672ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive: {
2682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportPrimitiveType *EPT =
2692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportPrimitiveType *>(ET);
2702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (EPT->isRSObjectType())
271cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao      return "null";
2722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    else if (EPT->getType() == DataTypeBoolean)
2732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      return "false";
2742ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    else
2752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      return "0";
2762ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
2772ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
2782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPointer:
2792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector:
2802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassMatrix:
2812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray:
2822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
2832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return "null";
2842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
2852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
2862ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default: { slangAssert(false && "Unknown class of type"); }
287cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao  }
288cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao  return "";
289cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao}
290cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao
29147aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hinesstatic std::string GetBuiltinElementConstruct(const RSExportType *ET) {
2922e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang  if (ET->getClass() == RSExportType::ExportClassPrimitive) {
293a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines    return std::string("Element.") + ET->getElementName();
2949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  } else if (ET->getClass() == RSExportType::ExportClassVector) {
2952ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportVectorType *EVT = static_cast<const RSExportVectorType *>(ET);
296cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet    if (EVT->getType() == DataTypeFloat32) {
297c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      if (EVT->getNumElement() == 2) {
2982b8fb64be3047df940a219872b331eb11de2758dStephen Hines        return "Element.F32_2";
299c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      } else if (EVT->getNumElement() == 3) {
3002b8fb64be3047df940a219872b331eb11de2758dStephen Hines        return "Element.F32_3";
301c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      } else if (EVT->getNumElement() == 4) {
3022b8fb64be3047df940a219872b331eb11de2758dStephen Hines        return "Element.F32_4";
303c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      } else {
304c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        slangAssert(false && "Vectors should be size 2, 3, 4");
305c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      }
306cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet    } else if (EVT->getType() == DataTypeUnsigned8) {
3072b8fb64be3047df940a219872b331eb11de2758dStephen Hines      if (EVT->getNumElement() == 4)
3082b8fb64be3047df940a219872b331eb11de2758dStephen Hines        return "Element.U8_4";
3099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
31092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang  } else if (ET->getClass() == RSExportType::ExportClassMatrix) {
31192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang    const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType *>(ET);
31292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang    switch (EMT->getDim()) {
3132ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case 2:
3142ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      return "Element.MATRIX_2X2";
3152ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case 3:
3162ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      return "Element.MATRIX_3X3";
3172ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case 4:
3182ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      return "Element.MATRIX_4X4";
3192ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    default:
3202ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      slangAssert(false && "Unsupported dimension of matrix");
32192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang    }
3229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
32347aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines  // RSExportType::ExportClassPointer can't be generated in a struct.
324462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
32547aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines  return "";
32648b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines}
32748b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
3287682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// If FromIntegerType == DestIntegerType, then Value is returned.
3297682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// Otherwise, return a Java expression that zero-extends the value
3307682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// Value, assumed to be of type FromIntegerType, to the integer type
3317682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// DestIntegerType.
3327682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala//
3337682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// Intended operations:
3347682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala//  byte  -> {byte,int,short,long}
3357682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala//  short -> {short,int,long}
3367682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala//  int   -> {int,long}
3377682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala//  long  -> long
3387682b663581dd8f67b422f6f2f31692ab2f870e3Matt Walastatic std::string ZeroExtendValue(const std::string &Value,
3397682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala                                   const std::string &FromIntegerType,
3407682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala                                   const std::string &DestIntegerType) {
3417682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala#ifndef __DISABLE_ASSERTS
3427682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  // Integer types arranged in increasing order by width
3437682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  const std::vector<std::string> ValidTypes{"byte", "short", "int", "long"};
3447682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  auto FromTypeLoc = std::find(ValidTypes.begin(), ValidTypes.end(), FromIntegerType);
3457682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  auto DestTypeLoc = std::find(ValidTypes.begin(), ValidTypes.end(), DestIntegerType);
3467682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  // Check that both types are valid.
3477682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  slangAssert(FromTypeLoc != ValidTypes.end());
3487682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  slangAssert(DestTypeLoc != ValidTypes.end());
3497682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  // Check that DestIntegerType is at least as wide as FromIntegerType.
3507682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  slangAssert(FromTypeLoc - ValidTypes.begin() <= DestTypeLoc - ValidTypes.begin());
3517682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala#endif
3527682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
3537682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  if (FromIntegerType == DestIntegerType) {
3547682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    return Value;
3557682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  }
3567682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
3577682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  std::string Mask, MaskLiteralType;
3587682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  if (FromIntegerType == "byte") {
3597682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    Mask = "0xff";
3607682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    MaskLiteralType = "int";
3617682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  } else if (FromIntegerType == "short") {
3627682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    Mask = "0xffff";
3637682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    MaskLiteralType = "int";
3647682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  } else if (FromIntegerType == "int") {
3657682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    Mask = "0xffffffffL";
3667682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    MaskLiteralType = "long";
3677682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  } else {
3687682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    // long -> long casts should have already been handled.
3697682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    slangAssert(false && "Unknown integer type");
3707682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  }
3717682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
3727682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  // Cast the mask to the appropriate type.
3737682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  if (MaskLiteralType != DestIntegerType) {
3747682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    Mask = "(" + DestIntegerType + ") " + Mask;
3757682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  }
3767682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  return "((" + DestIntegerType + ") ((" + Value + ") & " + Mask + "))";
3777682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala}
3787682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
3799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/********************** Methods to generate script class **********************/
38059f22c376b2c1cd109735280689224fadfe40b42Jean-Luc BrouilletRSReflectionJava::RSReflectionJava(const RSContext *Context,
38159f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                                   std::vector<std::string> *GeneratedFileNames,
38259f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                                   const std::string &OutputBaseDirectory,
38359f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                                   const std::string &RSSourceFileName,
38459f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                                   const std::string &BitCodeFileName,
38559f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                                   bool EmbedBitcodeInJava)
38659f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet    : mRSContext(Context), mPackageName(Context->getReflectJavaPackageName()),
38759f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet      mRSPackageName(Context->getRSPackageName()),
38859f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet      mOutputBaseDirectory(OutputBaseDirectory),
38959f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet      mRSSourceFileName(RSSourceFileName), mBitCodeFileName(BitCodeFileName),
39059f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet      mResourceId(RSSlangReflectUtils::JavaClassNameFromRSFileName(
39159f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet          mBitCodeFileName.c_str())),
39259f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet      mScriptClassName(RS_SCRIPT_CLASS_NAME_PREFIX +
39359f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                       RSSlangReflectUtils::JavaClassNameFromRSFileName(
39459f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                           mRSSourceFileName.c_str())),
395c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      mEmbedBitcodeInJava(EmbedBitcodeInJava), mNextExportVarSlot(0),
3967682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala      mNextExportFuncSlot(0), mNextExportForEachSlot(0),
3971c6bf88e098c767c3cd445f2c2514f0598d91501David Gross      mNextExportReduceSlot(0), mLastError(""),
398c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      mGeneratedFileNames(GeneratedFileNames), mFieldIndex(0) {
39959f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet  slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames");
40059f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet  slangAssert(!mPackageName.empty() && mPackageName != "-");
40159f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet
40259f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet  mOutputDirectory = RSSlangReflectUtils::ComputePackagedPath(
40359f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                         OutputBaseDirectory.c_str(), mPackageName.c_str()) +
40459f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                     OS_PATH_SEPARATOR_STR;
4053a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray
4063a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray  // mElement.getBytesSize only exists on JB+
4073a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray  if (mRSContext->getTargetAPI() >= SLANG_JB_TARGET_API) {
4083a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray      mItemSizeof = RS_TYPE_ITEM_SIZEOF_CURRENT;
4093a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray  } else {
4103a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray      mItemSizeof = RS_TYPE_ITEM_SIZEOF_LEGACY;
4113a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray  }
41259f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet}
41359f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet
4142e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletbool RSReflectionJava::genScriptClass(const std::string &ClassName,
415602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                      std::string &ErrorMsg) {
4162e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  if (!startClass(AM_Public, false, ClassName, RS_SCRIPT_CLASS_SUPER_CLASS_NAME,
4172e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  ErrorMsg))
4189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
4199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4202e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genScriptClassConstructor();
4219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4227682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  // Reflect exported variables
4237682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  for (auto I = mRSContext->export_vars_begin(),
4247682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala            E = mRSContext->export_vars_end();
4252ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++)
4262e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genExportVariable(*I);
4279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4287682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  // Reflect exported forEach functions (only available on ICS+)
4294cc499d6e5ec602309501873449c938af61170b2Stephen Hines  if (mRSContext->getTargetAPI() >= SLANG_ICS_TARGET_API) {
4307682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    for (auto I = mRSContext->export_foreach_begin(),
4317682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala              E = mRSContext->export_foreach_end();
4327682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala         I != E; I++) {
4332e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genExportForEach(*I);
4347682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    }
4354a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines  }
436593a894650e81be54173106ec266f0311cebebd3Stephen Hines
437277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Reflect exported new-style reduce functions
4381c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  for (const RSExportType *ResultType : mRSContext->getReduceResultTypes(
439277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross           // FilterIn
4401c6bf88e098c767c3cd445f2c2514f0598d91501David Gross           exportableReduce,
441277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
442277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross           // Compare
443277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross           [](const RSExportType *A, const RSExportType *B)
4441c6bf88e098c767c3cd445f2c2514f0598d91501David Gross           { return GetReduceResultTypeName(A) < GetReduceResultTypeName(B); }))
4451c6bf88e098c767c3cd445f2c2514f0598d91501David Gross    genExportReduceResultType(ResultType);
4461c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  for (auto I = mRSContext->export_reduce_begin(),
4471c6bf88e098c767c3cd445f2c2514f0598d91501David Gross            E = mRSContext->export_reduce_end();
448277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross       I != E; ++I)
4491c6bf88e098c767c3cd445f2c2514f0598d91501David Gross    genExportReduce(*I);
450277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
4517682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  // Reflect exported functions (invokable)
4527682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  for (auto I = mRSContext->export_funcs_begin(),
4537682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala            E = mRSContext->export_funcs_end();
4547682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala       I != E; ++I)
4552e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genExportFunction(*I);
4569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4572e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endClass();
4589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
4609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
461462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4622e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genScriptClassConstructor() {
4634c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines  std::string className(RSSlangReflectUtils::JavaBitcodeClassNameFromRSFileName(
46459f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet      mRSSourceFileName.c_str()));
465d2936939ec10879e25746322db60071f79f28c1bStephen Hines  // Provide a simple way to reference this object.
466f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "private static final String " RS_RESOURCE_NAME " = \""
467f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << getResourceId() << "\";\n";
468d2936939ec10879e25746322db60071f79f28c1bStephen Hines
469d2936939ec10879e25746322db60071f79f28c1bStephen Hines  // Generate a simple constructor with only a single parameter (the rest
470d2936939ec10879e25746322db60071f79f28c1bStephen Hines  // can be inferred from information we already have).
471f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "// Constructor\n";
4725abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  startFunction(AM_Public, false, nullptr, getClassName(), 1, "RenderScript",
4732e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "rs");
47444d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines
4757682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  const bool haveReduceExportables =
4761c6bf88e098c767c3cd445f2c2514f0598d91501David Gross    mRSContext->export_reduce_begin() != mRSContext->export_reduce_end();
4777682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
4782e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  if (getEmbedBitcodeInJava()) {
4794c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines    // Call new single argument Java-only constructor
480f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "super(rs,\n";
481f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "      " << RS_RESOURCE_NAME ",\n";
482f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "      " << className << ".getBitCode32(),\n";
4839ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    mOut.indent() << "      " << className << ".getBitCode64());\n";
4844c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines  } else {
4854c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines    // Call alternate constructor with required parameters.
4864c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines    // Look up the proper raw bitcode resource id via the context.
487f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "this(rs,\n";
488f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "     rs.getApplicationContext().getResources(),\n";
489f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "     rs.getApplicationContext().getResources()."
490f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                     "getIdentifier(\n";
491f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "         " RS_RESOURCE_NAME ", \"raw\",\n";
492f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent()
493f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        << "         rs.getApplicationContext().getPackageName()));\n";
4942e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    endFunction();
4954c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines
4964c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines    // Alternate constructor (legacy) with 3 original parameters.
4975abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    startFunction(AM_Public, false, nullptr, getClassName(), 3, "RenderScript",
4982e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  "rs", "Resources", "resources", "int", "id");
4994c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines    // Call constructor of super class
500f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "super(rs, resources, id);\n";
50144d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines  }
502b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams
503b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams  // If an exported variable has initial value, reflect it
504b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams
5057682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  for (auto I = mRSContext->export_vars_begin(),
5067682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala            E = mRSContext->export_vars_end();
5072ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++) {
508b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams    const RSExportVar *EV = *I;
509d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines    if (!EV->getInit().isUninit()) {
5102e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genInitExportVariable(EV->getType(), EV->getName(), EV->getInit());
511d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines    } else if (EV->getArraySize()) {
512d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      // Always create an initial zero-init array object.
513f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = new "
514277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                    << GetTypeName(EV->getType(), TypeNameDefault & ~TypeNameWithConstantArrayBrackets) << "["
515f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << EV->getArraySize() << "];\n";
516d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      size_t NumInits = EV->getNumInits();
517d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      const RSExportConstantArrayType *ECAT =
5182ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet          static_cast<const RSExportConstantArrayType *>(EV->getType());
519d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      const RSExportType *ET = ECAT->getElementType();
520d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      for (size_t i = 0; i < NumInits; i++) {
521d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        std::stringstream Name;
522d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        Name << EV->getName() << "[" << i << "]";
5232e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        genInitExportVariable(ET, Name.str(), EV->getInitArray(i));
524d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      }
525d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines    }
526a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines    if (mRSContext->getTargetAPI() >= SLANG_JB_TARGET_API) {
5272e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genTypeInstance(EV->getType());
528a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines    }
5292e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genFieldPackerInstance(EV->getType());
530b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams  }
531b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams
5327682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  if (haveReduceExportables) {
5337682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    mOut.indent() << SAVED_RS_REFERENCE << " = rs;\n";
5347682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  }
5357682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
5367682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  // Reflect argument / return types in kernels
5377682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
5387682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  for (auto I = mRSContext->export_foreach_begin(),
5397682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala            E = mRSContext->export_foreach_end();
5402ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++) {
54148b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    const RSExportForEach *EF = *I;
54248b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
543c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    const RSExportForEach::InTypeVec &InTypes = EF->getInTypes();
544c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    for (RSExportForEach::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
545c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes         BI != EI; BI++) {
5465abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes      if (*BI != nullptr) {
547c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        genTypeInstanceFromPointer(*BI);
548c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      }
54948b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    }
550c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
55148b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    const RSExportType *OET = EF->getOutType();
55248b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    if (OET) {
5532e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genTypeInstanceFromPointer(OET);
55448b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    }
55548b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  }
55648b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
5577682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  for (auto I = mRSContext->export_reduce_begin(),
5587682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala            E = mRSContext->export_reduce_end();
5597682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala       I != E; I++) {
5607682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    const RSExportReduce *ER = *I;
561277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
562277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const RSExportType *RT = ER->getResultType();
563277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    slangAssert(RT != nullptr);
5641c6bf88e098c767c3cd445f2c2514f0598d91501David Gross    if (!exportableReduce(RT))
565277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      continue;
566277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
567277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    genTypeInstance(RT);
568277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
5691c6bf88e098c767c3cd445f2c2514f0598d91501David Gross    const RSExportReduce::InTypeVec &InTypes = ER->getAccumulatorInTypes();
5701c6bf88e098c767c3cd445f2c2514f0598d91501David Gross    for (RSExportReduce::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
571277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross         BI != EI; BI++) {
572277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      slangAssert(*BI != nullptr);
573277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      genTypeInstance(*BI);
574277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
575277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
576277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
5772e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
578b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams
5792e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  for (std::set<std::string>::iterator I = mTypesToCheck.begin(),
5802e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                       E = mTypesToCheck.end();
5812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++) {
582f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "private Element " RS_ELEM_PREFIX << *I << ";\n";
58348b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  }
58448b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
5852e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  for (std::set<std::string>::iterator I = mFieldPackerTypes.begin(),
5862e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                       E = mFieldPackerTypes.end();
5872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++) {
588f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "private FieldPacker " RS_FP_PREFIX << *I << ";\n";
5891f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  }
5907682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
5917682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  if (haveReduceExportables) {
5927682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    // We save a private copy of rs in order to create temporary
5937682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    // allocations in the reduce_* entry points.
5947682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala    mOut.indent() << "private RenderScript " << SAVED_RS_REFERENCE << ";\n";
5957682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  }
5969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
597462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
5982e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genInitBoolExportVariable(const std::string &VarName,
599602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                                 const clang::APValue &Val) {
6006e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert(!Val.isUninit() && "Not a valid initializer");
6012ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  slangAssert((Val.getKind() == clang::APValue::Int) &&
6022ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet              "Bool type has wrong initial APValue");
603462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
604f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
605462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
606f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << ((Val.getInt().getSExtValue() == 0) ? "false" : "true") << ";\n";
607462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
608462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
6092e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid
6102e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc BrouilletRSReflectionJava::genInitPrimitiveExportVariable(const std::string &VarName,
6112e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                                 const clang::APValue &Val) {
6125d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines  slangAssert(!Val.isUninit() && "Not a valid initializer");
6135d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines
614f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
615efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  genInitValue(Val, false);
616f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << ";\n";
61748bac230fe966771f3074975fc2426ffde519edfShih-wei Liao}
61848bac230fe966771f3074975fc2426ffde519edfShih-wei Liao
6192e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genInitExportVariable(const RSExportType *ET,
620602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                             const std::string &VarName,
621602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                             const clang::APValue &Val) {
6226e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert(!Val.isUninit() && "Not a valid initializer");
6239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
6249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  switch (ET->getClass()) {
6252ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive: {
6262ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportPrimitiveType *EPT =
6272ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportPrimitiveType *>(ET);
6282ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (EPT->getType() == DataTypeBoolean) {
6292e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genInitBoolExportVariable(VarName, Val);
6302ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    } else {
6312e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genInitPrimitiveExportVariable(VarName, Val);
632324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao    }
6332ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
6342ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
6352ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPointer: {
6362ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (!Val.isInt() || Val.getInt().getSExtValue() != 0)
6372ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      std::cout << "Initializer which is non-NULL to pointer type variable "
6382ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                   "will be ignored\n";
6392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
6402ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
6412ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector: {
6422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportVectorType *EVT = static_cast<const RSExportVectorType *>(ET);
6432ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    switch (Val.getKind()) {
6442ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Int:
6452ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Float: {
6462ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      for (unsigned i = 0; i < EVT->getNumElement(); i++) {
6472ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        std::string Name = VarName + "." + GetVectorAccessor(i);
6482e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        genInitPrimitiveExportVariable(Name, Val);
6492ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      }
6509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
6519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
6522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Vector: {
6532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      std::stringstream VecName;
6542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      VecName << EVT->getRSReflectionType(EVT)->rs_java_vector_prefix
6552ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet              << EVT->getNumElement();
656f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new "
657f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << VecName.str() << "();\n";
6582ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
6592ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      unsigned NumElements = std::min(
6602ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet          static_cast<unsigned>(EVT->getNumElement()), Val.getVectorLength());
6612ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      for (unsigned i = 0; i < NumElements; i++) {
6622ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        const clang::APValue &ElementVal = Val.getVectorElt(i);
6632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        std::string Name = VarName + "." + GetVectorAccessor(i);
6642e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        genInitPrimitiveExportVariable(Name, ElementVal);
6659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
6669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
667324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao    }
6682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::MemberPointer:
6692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Uninitialized:
6702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::ComplexInt:
6712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::ComplexFloat:
6722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::LValue:
6732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Array:
6742ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Struct:
6752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Union:
6762ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::AddrLabelDiff: {
6772ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      slangAssert(false && "Unexpected type of value of initializer.");
6782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
6792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
6802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
6812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
6822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  // TODO(zonr): Resolving initializer of a record (and matrix) type variable
6832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  // is complex. It cannot obtain by just simply evaluating the initializer
6842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  // expression.
6852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassMatrix:
6862ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray:
6872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
6889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#if 0
6899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      unsigned InitIndex = 0;
6906315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportRecordType *ERT =
6916315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr          static_cast<const RSExportRecordType*>(ET);
692462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
6936e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert((Val.getKind() == clang::APValue::Vector) &&
6946e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines          "Unexpected type of initializer for record type variable");
695462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
696f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName
697a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines                 << " = new " << ERT->getElementName()
6982968921e1cedf85360964c5a39e1ce36c66ecd09Jean-Luc Brouillet                 <<  "." RS_TYPE_ITEM_CLASS_NAME"();\n";
699462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
7009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
7019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao               E = ERT->fields_end();
7029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao           I != E;
7039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao           I++) {
7049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const RSExportRecordType::Field *F = *I;
7059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        std::string FieldName = VarName + "." + F->getName();
706462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
7079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (InitIndex > Val.getVectorLength())
7089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          break;
709462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
710f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        genInitPrimitiveExportVariable(FieldName,
7119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                       Val.getVectorElt(InitIndex++));
7129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
7139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#endif
7142ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    slangAssert(false && "Unsupported initializer for record/matrix/constant "
7152ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                         "array type variable currently");
7162ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
7172ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
7182ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default: { slangAssert(false && "Unknown class of type"); }
7199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
720462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
721462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
7222e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genExportVariable(const RSExportVar *EV) {
7239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const RSExportType *ET = EV->getType();
724462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
725f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "private final static int " << RS_EXPORT_VAR_INDEX_PREFIX
726f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << EV->getName() << " = " << getNextExportVarSlot() << ";\n";
727462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
7289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  switch (ET->getClass()) {
7292ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive: {
7302e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genPrimitiveTypeExportVariable(EV);
7312ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
7322ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
7332ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPointer: {
7342e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genPointerTypeExportVariable(EV);
7352ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
7362ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
7372ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector: {
7382e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genVectorTypeExportVariable(EV);
7392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
7402ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
7412ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassMatrix: {
7422e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genMatrixTypeExportVariable(EV);
7432ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
7442ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
7452ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray: {
7462e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genConstantArrayTypeExportVariable(EV);
7472ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
7482ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
7492ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
7502e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genRecordTypeExportVariable(EV);
7512ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
7522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
7532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default: { slangAssert(false && "Unknown class of type"); }
7549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
755462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
756462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
7572e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genExportFunction(const RSExportFunc *EF) {
758f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "private final static int " << RS_EXPORT_FUNC_INDEX_PREFIX
759f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << EF->getName() << " = " << getNextExportFuncSlot() << ";\n";
7609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
7619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // invoke_*()
7622e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  ArgTy Args;
7639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
7640da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang  if (EF->hasParam()) {
7650da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang    for (RSExportFunc::const_param_iterator I = EF->params_begin(),
7662ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                            E = EF->params_end();
7672ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet         I != E; I++) {
7682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      Args.push_back(
7692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet          std::make_pair(GetTypeName((*I)->getType()), (*I)->getName()));
7700da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang    }
7719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
7729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
773bd0a7ddceac6c135ea975cefbac73877a1f9dae7Stephen Hines  if (mRSContext->getTargetAPI() >= SLANG_M_TARGET_API) {
774cec2a1d2e38ebd644c9f63e83bf5649f15df99d5Yang Ni    startFunction(AM_Public, false, "Script.InvokeID",
775cec2a1d2e38ebd644c9f63e83bf5649f15df99d5Yang Ni                  "getInvokeID_" + EF->getName(), 0);
776cec2a1d2e38ebd644c9f63e83bf5649f15df99d5Yang Ni
777cec2a1d2e38ebd644c9f63e83bf5649f15df99d5Yang Ni    mOut.indent() << "return createInvokeID(" << RS_EXPORT_FUNC_INDEX_PREFIX
778cec2a1d2e38ebd644c9f63e83bf5649f15df99d5Yang Ni                  << EF->getName() << ");\n";
779cec2a1d2e38ebd644c9f63e83bf5649f15df99d5Yang Ni
780cec2a1d2e38ebd644c9f63e83bf5649f15df99d5Yang Ni    endFunction();
781cec2a1d2e38ebd644c9f63e83bf5649f15df99d5Yang Ni  }
782cec2a1d2e38ebd644c9f63e83bf5649f15df99d5Yang Ni
7832e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, false, "void",
7842e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "invoke_" + EF->getName(/*Mangle=*/false),
7852e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                // We are using un-mangled name since Java
7862e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                // supports method overloading.
7872e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                Args);
7889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
7899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!EF->hasParam()) {
790f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "invoke(" << RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName()
791f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << ");\n";
7929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  } else {
7939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    const RSExportRecordType *ERT = EF->getParamPacketType();
7949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    std::string FieldPackerName = EF->getName() + "_fp";
7959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
7962e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    if (genCreateFieldPacker(ERT, FieldPackerName.c_str()))
7975abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes      genPackVarOfType(ERT, nullptr, FieldPackerName.c_str());
7989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
799f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "invoke(" << RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName()
800f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << ", " << FieldPackerName << ");\n";
8019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
8029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
8032e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
8049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
805462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
806e2ead846c1d78a6e7108e521ffd15850bd9eed3cChih-Hung Hsiehvoid RSReflectionJava::genPairwiseDimCheck(const std::string &name0,
807e2ead846c1d78a6e7108e521ffd15850bd9eed3cChih-Hung Hsieh                                           const std::string &name1) {
808c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
809c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "// Verify dimensions\n";
810c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "t0 = " << name0 << ".getType();\n";
811c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "t1 = " << name1 << ".getType();\n";
812c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "if ((t0.getCount() != t1.getCount()) ||\n";
813c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "    (t0.getX() != t1.getX()) ||\n";
814c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "    (t0.getY() != t1.getY()) ||\n";
815c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "    (t0.getZ() != t1.getZ()) ||\n";
816c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "    (t0.hasFaces()   != t1.hasFaces()) ||\n";
817c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "    (t0.hasMipmaps() != t1.hasMipmaps())) {\n";
818c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "    throw new RSRuntimeException(\"Dimension mismatch "
819c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes                << "between parameters " << name0 << " and " << name1
820c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes                << "!\");\n";
821c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  mOut.indent() << "}\n\n";
822c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes}
823c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
824277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Grossvoid RSReflectionJava::genNullArrayCheck(const std::string &ArrayName) {
8257682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  mOut.indent() << "// Verify that \"" << ArrayName << "\" is non-null.\n";
8267682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  mOut.indent() << "if (" << ArrayName << " == null) {\n";
8277682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  mOut.indent() << "    throw new RSIllegalArgumentException(\"Array \\\""
8287682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala                << ArrayName << "\\\" is null!\");\n";
8297682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  mOut.indent() << "}\n";
830277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
831277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
8327682b663581dd8f67b422f6f2f31692ab2f870e3Matt Walavoid RSReflectionJava::genVectorLengthCompatibilityCheck(const std::string &ArrayName,
8337682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala                                                         unsigned VecSize) {
8347682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  mOut.indent() << "// Verify that the array length is a multiple of the vector size.\n";
8357682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  mOut.indent() << "if (" << ArrayName << ".length % " << std::to_string(VecSize)
8367682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala                << " != 0) {\n";
8377682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  mOut.indent() << "    throw new RSIllegalArgumentException(\"Array \\\"" << ArrayName
8387682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala                << "\\\" is not a multiple of " << std::to_string(VecSize)
8397682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala                << " in length!\");\n";
8407682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala  mOut.indent() << "}\n";
8417682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala}
8427682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala
8432e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genExportForEach(const RSExportForEach *EF) {
844c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  if (EF->isDummyRoot()) {
845c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines    // Skip reflection for dummy root() kernels. Note that we have to
846c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines    // advance the next slot number for ForEach, however.
847f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "//private final static int "
848f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << RS_EXPORT_FOREACH_INDEX_PREFIX << EF->getName() << " = "
849f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << getNextExportForEachSlot() << ";\n";
850c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines    return;
851c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  }
852c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
853f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "private final static int " << RS_EXPORT_FOREACH_INDEX_PREFIX
854f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << EF->getName() << " = " << getNextExportForEachSlot()
855f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << ";\n";
856593a894650e81be54173106ec266f0311cebebd3Stephen Hines
857b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  // forEach_*()
8582e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  ArgTy Args;
859fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross  bool HasAllocation = false; // at least one in/out allocation?
860593a894650e81be54173106ec266f0311cebebd3Stephen Hines
861c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  const RSExportForEach::InVec     &Ins     = EF->getIns();
862c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  const RSExportForEach::InTypeVec &InTypes = EF->getInTypes();
863c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  const RSExportType               *OET     = EF->getOutType();
864c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
865c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  if (Ins.size() == 1) {
866fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross    HasAllocation = true;
867b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    Args.push_back(std::make_pair("Allocation", "ain"));
868c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
869c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  } else if (Ins.size() > 1) {
870fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross    HasAllocation = true;
871c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    for (RSExportForEach::InIter BI = Ins.begin(), EI = Ins.end(); BI != EI;
872c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes         BI++) {
873c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
874c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      Args.push_back(std::make_pair("Allocation",
875c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes                                    "ain_" + (*BI)->getName().str()));
876c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    }
877c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  }
878c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
879fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross  if (EF->hasOut() || EF->hasReturn()) {
880fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross    HasAllocation = true;
881593a894650e81be54173106ec266f0311cebebd3Stephen Hines    Args.push_back(std::make_pair("Allocation", "aout"));
882fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross  }
883b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
884b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  const RSExportRecordType *ERT = EF->getParamPacketType();
885b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  if (ERT) {
886b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    for (RSExportForEach::const_param_iterator I = EF->params_begin(),
8872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                               E = EF->params_end();
8882ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet         I != E; I++) {
8892ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      Args.push_back(
8902ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet          std::make_pair(GetTypeName((*I)->getType()), (*I)->getName()));
891593a894650e81be54173106ec266f0311cebebd3Stephen Hines    }
892593a894650e81be54173106ec266f0311cebebd3Stephen Hines  }
893593a894650e81be54173106ec266f0311cebebd3Stephen Hines
894b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray  if (mRSContext->getTargetAPI() >= SLANG_JB_MR1_TARGET_API) {
8952e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    startFunction(AM_Public, false, "Script.KernelID",
8962e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  "getKernelID_" + EF->getName(), 0);
897b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray
8982ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // TODO: add element checking
899f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "return createKernelID(" << RS_EXPORT_FOREACH_INDEX_PREFIX
900c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes                  << EF->getName() << ", " << EF->getSignatureMetadata()
901c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes                  << ", null, null);\n";
902b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray
9032e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    endFunction();
904b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray  }
905b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray
90650974740c0c5c52dd766264139a01702fbc138afStephen Hines  if (mRSContext->getTargetAPI() >= SLANG_JB_MR2_TARGET_API) {
907fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross    if (HasAllocation) {
908fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross      startFunction(AM_Public, false, "void", "forEach_" + EF->getName(), Args);
90950974740c0c5c52dd766264139a01702fbc138afStephen Hines
910fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross      mOut.indent() << "forEach_" << EF->getName();
911fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross      mOut << "(";
91250974740c0c5c52dd766264139a01702fbc138afStephen Hines
913fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross      if (Ins.size() == 1) {
914fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross        mOut << "ain, ";
915c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
916fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross      } else if (Ins.size() > 1) {
917fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross        for (RSExportForEach::InIter BI = Ins.begin(), EI = Ins.end(); BI != EI;
918fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross             BI++) {
919c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
920fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross          mOut << "ain_" << (*BI)->getName().str() << ", ";
921fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross        }
922c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      }
92350974740c0c5c52dd766264139a01702fbc138afStephen Hines
924fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross      if (EF->hasOut() || EF->hasReturn()) {
925fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross        mOut << "aout, ";
926fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross      }
92750974740c0c5c52dd766264139a01702fbc138afStephen Hines
928fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross      if (EF->hasUsrData()) {
929fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross        mOut << Args.back().second << ", ";
930fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross      }
93150974740c0c5c52dd766264139a01702fbc138afStephen Hines
932fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross      // No clipped bounds to pass in.
933fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross      mOut << "null);\n";
93450974740c0c5c52dd766264139a01702fbc138afStephen Hines
935fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross      endFunction();
936fb78d4c6604bd243578ce8071e31f68c023d82cfDavid Gross    }
93750974740c0c5c52dd766264139a01702fbc138afStephen Hines
93850974740c0c5c52dd766264139a01702fbc138afStephen Hines    // Add the clipped kernel parameters to the Args list.
93950974740c0c5c52dd766264139a01702fbc138afStephen Hines    Args.push_back(std::make_pair("Script.LaunchOptions", "sc"));
94050974740c0c5c52dd766264139a01702fbc138afStephen Hines  }
94150974740c0c5c52dd766264139a01702fbc138afStephen Hines
9422e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, false, "void", "forEach_" + EF->getName(), Args);
943593a894650e81be54173106ec266f0311cebebd3Stephen Hines
944c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  if (InTypes.size() == 1) {
9455abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    if (InTypes.front() != nullptr) {
946c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      genTypeCheck(InTypes.front(), "ain");
947c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    }
948c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
949c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  } else if (InTypes.size() > 1) {
950c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    size_t Index = 0;
951c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    for (RSExportForEach::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
952c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes         BI != EI; BI++, ++Index) {
953c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
9545abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes      if (*BI != nullptr) {
955c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        genTypeCheck(*BI, ("ain_" + Ins[Index]->getName()).str().c_str());
956c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      }
957c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    }
958b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  }
959c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
960b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  if (OET) {
9612e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genTypeCheck(OET, "aout");
962593a894650e81be54173106ec266f0311cebebd3Stephen Hines  }
963593a894650e81be54173106ec266f0311cebebd3Stephen Hines
964c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  if (Ins.size() == 1 && (EF->hasOut() || EF->hasReturn())) {
965c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    mOut.indent() << "Type t0, t1;";
966c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    genPairwiseDimCheck("ain", "aout");
967c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
968c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  } else if (Ins.size() > 1) {
969c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    mOut.indent() << "Type t0, t1;";
970c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
971c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    std::string In0Name = "ain_" + Ins[0]->getName().str();
972c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
973c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    for (size_t index = 1; index < Ins.size(); ++index) {
974c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      genPairwiseDimCheck(In0Name, "ain_" + Ins[index]->getName().str());
975c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    }
976c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
977c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    if (EF->hasOut() || EF->hasReturn()) {
978c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      genPairwiseDimCheck(In0Name, "aout");
979c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    }
980593a894650e81be54173106ec266f0311cebebd3Stephen Hines  }
981593a894650e81be54173106ec266f0311cebebd3Stephen Hines
982b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  std::string FieldPackerName = EF->getName() + "_fp";
983b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  if (ERT) {
9842e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    if (genCreateFieldPacker(ERT, FieldPackerName.c_str())) {
9855abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes      genPackVarOfType(ERT, nullptr, FieldPackerName.c_str());
986b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    }
987b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  }
988f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "forEach(" << RS_EXPORT_FOREACH_INDEX_PREFIX
989f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << EF->getName();
990b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
991c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  if (Ins.size() == 1) {
992f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << ", ain";
993c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  } else if (Ins.size() > 1) {
994c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    mOut << ", new Allocation[]{ain_" << Ins[0]->getName().str();
995c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
996c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    for (size_t index = 1; index < Ins.size(); ++index) {
997c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      mOut << ", ain_" << Ins[index]->getName().str();
998c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    }
999c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
1000c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    mOut << "}";
1001c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
1002c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  } else {
1003c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    mOut << ", (Allocation) null";
1004c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  }
1005b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
10069ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines  if (EF->hasOut() || EF->hasReturn())
1007f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << ", aout";
1008b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  else
1009f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << ", null";
1010b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
1011b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  if (EF->hasUsrData())
1012f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << ", " << FieldPackerName;
1013b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  else
1014f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << ", null";
1015b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
101650974740c0c5c52dd766264139a01702fbc138afStephen Hines  if (mRSContext->getTargetAPI() >= SLANG_JB_MR2_TARGET_API) {
1017f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << ", sc);\n";
101850974740c0c5c52dd766264139a01702fbc138afStephen Hines  } else {
1019f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << ");\n";
102050974740c0c5c52dd766264139a01702fbc138afStephen Hines  }
1021b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
10222e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
1023593a894650e81be54173106ec266f0311cebebd3Stephen Hines}
1024593a894650e81be54173106ec266f0311cebebd3Stephen Hines
1025277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//////////////////////////////////////////////////////////////////////////////////////////////////////
1026277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1027277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// Reductions with certain legal result types can only be reflected for NDK, not for Java.
10281c6bf88e098c767c3cd445f2c2514f0598d91501David Grossbool RSReflectionJava::exportableReduce(const RSExportType *ResultType) {
1029277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const RSExportType *CheckType = ResultType;
1030277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  if (ResultType->getClass() == RSExportType::ExportClassConstantArray)
1031277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    CheckType = static_cast<const RSExportConstantArrayType *>(ResultType)->getElementType();
1032277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  if (CheckType->getClass() == RSExportType::ExportClassRecord) {
1033277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    // No Java reflection for struct until http://b/22236498 is resolved.
1034277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    return false;
1035277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1036277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1037277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  return true;
1038277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1039277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1040277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Grossnamespace {
1041277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Grossenum MappingComment { MappingCommentWithoutType, MappingCommentWithCType };
1042277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1043277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// OUTPUTS
1044277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//   InputParamName      = name to use for input parameter
1045277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//   InputMappingComment = text showing the mapping from InputParamName to the corresponding
1046277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//                           accumulator function parameter name (and possibly type)
1047277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// INPUTS
1048277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//   NamePrefix          = beginning of parameter name (e.g., "in")
1049277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//   MappingComment      = whether or not InputMappingComment should contain type
1050277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//   ER                  = description of the reduction
1051277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//   InIdx               = which input (numbered from zero)
10521c6bf88e098c767c3cd445f2c2514f0598d91501David Grossvoid getReduceInputStrings(std::string &InputParamName, std::string &InputMappingComment,
10531c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                           const std::string &NamePrefix, MappingComment Mapping,
10541c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                           const RSExportReduce *ER, size_t InIdx) {
1055277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  InputParamName = NamePrefix + std::to_string(InIdx+1);
1056277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  std::string TypeString;
1057277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  if (Mapping == MappingCommentWithCType) {
1058277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const RSExportType *InType = ER->getAccumulatorInTypes()[InIdx];
1059277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (InType->getClass() == RSExportType::ExportClassRecord) {
1060277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      // convertToRTD doesn't understand this type
1061277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      TypeString = "/* struct <> */ ";
1062277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    } else {
1063277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      RSReflectionTypeData InTypeData;
1064277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      ER->getAccumulatorInTypes()[InIdx]->convertToRTD(&InTypeData);
1065277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      slangAssert(InTypeData.type->s_name != nullptr);
1066277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      if (InTypeData.vecSize > 1) {
1067277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        TypeString = InTypeData.type->s_name + std::to_string(InTypeData.vecSize) + " ";
1068277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      } else {
1069277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        TypeString = InTypeData.type->s_name + std::string(" ");
1070277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      }
1071277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1072277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1073277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  InputMappingComment = InputParamName + " = \"" + TypeString + std::string(ER->getAccumulatorIns()[InIdx]->getName()) + "\"";
1074277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1075277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1076277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross} // end anonymous namespace
1077277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
10781c6bf88e098c767c3cd445f2c2514f0598d91501David Grossvoid RSReflectionJava::genExportReduce(const RSExportReduce *ER) {
10791c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  if (!exportableReduce(ER->getResultType()))
1080277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    return;
1081277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1082277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Generate the reflected function index.
10831c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  mOut.indent() << "private final static int " << RS_EXPORT_REDUCE_INDEX_PREFIX
10841c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                << ER->getNameReduce() << " = " << getNextExportReduceSlot()
1085277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                << ";\n";
1086277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1087277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  /****** remember resultSvType generation **********************************************************/
1088277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1089277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Two variants of reduce_* entry points get generated.
1090277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Array variant:
1091277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  //   result_<resultSvType> reduce_<name>(<devecSiIn1Type>[] in1, ..., <devecSiInNType>[] inN)
1092277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Allocation variant:
1093277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  //   result_<resultSvType> reduce_<name>(Allocation in1, ..., Allocation inN)
1094277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  //   result_<resultSvType> reduce_<name>(Allocation in1, ..., Allocation inN, Script.LaunchOptions sc)
1095277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
10961c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  genExportReduceArrayVariant(ER);
10971c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  genExportReduceAllocationVariant(ER);
1098277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1099277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
11001c6bf88e098c767c3cd445f2c2514f0598d91501David Grossvoid RSReflectionJava::genExportReduceArrayVariant(const RSExportReduce *ER) {
1101277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Analysis of result type.  Returns early if result type is not
1102277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // suitable for array method reflection.
1103277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const RSExportType *const ResultType = ER->getResultType();
1104277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  auto ResultTypeClass = ResultType->getClass();
1105277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  switch (ResultTypeClass) {
1106277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassConstantArray:
1107277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassMatrix:
1108277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassPrimitive:
1109277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassVector:
1110277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        // Ok
1111277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        break;
1112277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1113277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassPointer:
1114277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        slangAssert(!"Should not get here with pointer type");
1115277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        return;
1116277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1117277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassRecord:
1118277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        // TODO: convertToRTD() cannot handle this.  Why not?
1119277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        return;
1120277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1121277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      default:
1122277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        slangAssert(!"Unknown export class");
1123277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        return;
1124277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1125277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  RSReflectionTypeData ResultTypeData;
1126277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  ResultType->convertToRTD(&ResultTypeData);
1127277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  if (!ResultTypeData.type->java_name || !ResultTypeData.type->java_array_element_name ||
1128277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      (ResultTypeData.vecSize > 1 && !ResultTypeData.type->rs_java_vector_prefix)) {
1129991096ff0ab7d2dc124994c0a40290212de349bdDavid Gross    slangAssert(false);
1130277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    return;
1131277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
11321c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  const std::string ResultTypeName = GetReduceResultTypeName(ER);
1133277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1134277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Analysis of inputs.  Returns early if some input type is not
1135277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // suitable for array method reflection.
1136277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  llvm::SmallVector<RSReflectionTypeData, 1> InsTypeData;
1137277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  ArgTy Args;
1138277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const auto &Ins = ER->getAccumulatorIns();
1139277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const auto &InTypes = ER->getAccumulatorInTypes();
1140277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  slangAssert(Ins.size() == InTypes.size());
1141277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  InsTypeData.resize(Ins.size());
1142277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  llvm::SmallVector<std::string, 1> InComments;
1143277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (size_t InIdx = 0, InEnd = Ins.size(); InIdx < InEnd; ++InIdx) {
1144277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const RSExportType *const InType = InTypes[InIdx];
1145277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    switch (InType->getClass()) {
1146277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassMatrix:
1147277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassPrimitive:
1148277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassVector:
1149277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        // Ok
1150277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        break;
1151277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1152277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassConstantArray:
1153277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        // No
1154277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        return;
1155277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1156277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassPointer:
1157277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        slangAssert(!"Should not get here with pointer type");
1158277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        return;
1159277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1160277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      case RSExportType::ExportClassRecord:
1161277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        // TODO: convertToRTD() cannot handle this.  Why not?
1162277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        return;
1163277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1164277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      default:
1165277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        slangAssert(!"Unknown export class");
1166277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        return;
1167277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1168277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1169277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    RSReflectionTypeData &InTypeData = InsTypeData[InIdx];
1170277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    InType->convertToRTD(&InTypeData);
1171277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (!InTypeData.type->java_name || !InTypeData.type->java_array_element_name ||
1172277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        (InTypeData.vecSize > 1 && !InTypeData.type->rs_java_vector_prefix)) {
1173277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      return;
1174277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1175277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1176277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    std::string InputParamName, InputComment;
11771c6bf88e098c767c3cd445f2c2514f0598d91501David Gross    getReduceInputStrings(InputParamName, InputComment, "in", MappingCommentWithoutType, ER, InIdx);
1178277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (InTypeData.vecSize > 1)
1179277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      InputComment += (", flattened " + std::to_string(InTypeData.vecSize) + "-vectors");
1180277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    InComments.push_back(InputComment);
1181277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1182277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const std::string InputTypeName = std::string(InTypeData.type->java_array_element_name) + "[]";
1183277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    Args.push_back(std::make_pair(InputTypeName, InputParamName));
1184277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1185277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1186277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const std::string MethodName = "reduce_" + ER->getNameReduce();
1187277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1188277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // result_<resultSvType> reduce_<name>(<devecSiIn1Type>[] in1, ..., <devecSiInNType>[] inN)
1189277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1190277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (const std::string &InComment : InComments)
1191277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << "// " << InComment << "\n";
1192277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  startFunction(AM_Public, false, ResultTypeName.c_str(), MethodName, Args);
1193277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  slangAssert(Ins.size() == InTypes.size());
1194277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  slangAssert(Ins.size() == InsTypeData.size());
1195277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  slangAssert(Ins.size() == Args.size());
11961381ae7c081ab151e78184501f757f517fe6c2a9David Gross  std::string In1Length;
11971381ae7c081ab151e78184501f757f517fe6c2a9David Gross  std::string InputAllocationOutgoingArgumentList;
11982b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  std::vector<std::string> InputAllocationNames;
1199277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (size_t InIdx = 0, InEnd = Ins.size(); InIdx < InEnd; ++InIdx) {
1200277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const std::string &ArgName = Args[InIdx].second;
1201277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    genNullArrayCheck(ArgName);
1202277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    std::string InLength = ArgName + ".length";
1203277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const uint32_t VecSize = InsTypeData[InIdx].vecSize;
1204277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (VecSize > 1) {
1205277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      InLength += " / " + std::to_string(VecSize);
1206277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      genVectorLengthCompatibilityCheck(ArgName, VecSize);
1207277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1208277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (InIdx == 0) {
12091381ae7c081ab151e78184501f757f517fe6c2a9David Gross      In1Length = InLength;
1210277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    } else {
1211277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.indent() << "// Verify that input array lengths are the same.\n";
12121381ae7c081ab151e78184501f757f517fe6c2a9David Gross      mOut.indent() << "if (" << In1Length << " != " << InLength << ") {\n";
1213277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.indent() << "    throw new RSRuntimeException(\"Array length mismatch "
1214277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                    << "between parameters \\\"" << Args[0].second << "\\\" and \\\"" << ArgName
1215277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                    << "\\\"!\");\n";
1216277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.indent() << "}\n";
1217277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1218277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    // Create a temporary input allocation
1219277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const std::string TempName = "a" + ArgName;
1220277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << "Allocation " << TempName << " = Allocation.createSized("
1221277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                  << SAVED_RS_REFERENCE << ", "
1222277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                  << RS_ELEM_PREFIX << InTypes[InIdx]->getElementName() << ", "
12231381ae7c081ab151e78184501f757f517fe6c2a9David Gross                  << InLength << ");\n";
1224277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << TempName << ".setAutoPadding(true);\n";
12251381ae7c081ab151e78184501f757f517fe6c2a9David Gross    mOut.indent() << TempName << ".copyFrom(" << ArgName << ");\n";
1226277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    // ... and put that input allocation on the outgoing argument list
1227277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (!InputAllocationOutgoingArgumentList.empty())
1228277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      InputAllocationOutgoingArgumentList += ", ";
1229277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    InputAllocationOutgoingArgumentList += TempName;
12302b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross    // ... and keep track of it for setting result.mTempIns
12312b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross    InputAllocationNames.push_back(TempName);
1232277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
12331381ae7c081ab151e78184501f757f517fe6c2a9David Gross
1234277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut << "\n";
12352b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << ResultTypeName << " result = " << MethodName << "(" << InputAllocationOutgoingArgumentList << ", null);\n";
12362b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  if (!InputAllocationNames.empty()) {
12372b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross    mOut.indent() << "result.mTempIns = new Allocation[]{";
12382b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross    bool EmittedFirst = false;
12392b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross    for (const std::string &InputAllocationName : InputAllocationNames) {
12402b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      if (!EmittedFirst) {
12412b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross        EmittedFirst = true;
12422b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      } else {
12432b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross        mOut << ", ";
12442b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      }
12452b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      mOut << InputAllocationName;
12462b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross    }
12472b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross    mOut << "};\n";
12482b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  }
12492b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "return result;\n";
1250277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  endFunction();
1251277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1252277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
12531c6bf88e098c767c3cd445f2c2514f0598d91501David Grossvoid RSReflectionJava::genExportReduceAllocationVariant(const RSExportReduce *ER) {
1254277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const auto &Ins = ER->getAccumulatorIns();
1255277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const auto &InTypes = ER->getAccumulatorInTypes();
1256277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const RSExportType *ResultType = ER->getResultType();
1257277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1258277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  llvm::SmallVector<std::string, 1> InComments;
1259277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  ArgTy Args;
1260277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (size_t InIdx = 0, InEnd = Ins.size(); InIdx < InEnd; ++InIdx) {
1261277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    std::string InputParamName, InputComment;
12621c6bf88e098c767c3cd445f2c2514f0598d91501David Gross    getReduceInputStrings(InputParamName, InputComment, "ain", MappingCommentWithCType, ER, InIdx);
1263277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    InComments.push_back(InputComment);
1264277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    Args.push_back(std::make_pair("Allocation", InputParamName));
1265277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1266277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1267277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const std::string MethodName = "reduce_" + ER->getNameReduce();
12681c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  const std::string ResultTypeName = GetReduceResultTypeName(ER);
1269277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1270277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // result_<resultSvType> reduce_<name>(Allocation in1, ..., Allocation inN)
1271277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1272277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (const std::string &InComment : InComments)
1273277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << "// " << InComment << "\n";
1274277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  startFunction(AM_Public, false, ResultTypeName.c_str(), MethodName, Args);
1275277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << "return " << MethodName << "(";
1276277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  bool EmittedFirstArg = false;
1277277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (const auto &Arg : Args) {
1278277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (!EmittedFirstArg) {
1279277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      EmittedFirstArg = true;
1280277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    } else {
1281277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut << ", ";
1282277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1283277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut << Arg.second;
1284277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1285277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut << ", null);\n";
1286277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  endFunction();
1287277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1288277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // result_<resultSvType> reduce_<name>(Allocation in1, ..., Allocation inN, Script.LaunchOptions sc)
1289277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1290277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  static const char FormalOptionsName[] = "sc";
1291277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  Args.push_back(std::make_pair("Script.LaunchOptions", FormalOptionsName));
1292277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (const std::string &InComment : InComments)
1293277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << "// " << InComment << "\n";
1294277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  startFunction(AM_Public, false, ResultTypeName.c_str(), MethodName, Args);
1295277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const std::string &In0Name = Args[0].second;
1296277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Sanity-check inputs
1297277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  if (Ins.size() > 1)
1298277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << "Type t0, t1;\n";
1299277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (size_t InIdx = 0, InEnd = Ins.size(); InIdx < InEnd; ++InIdx) {
1300277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const std::string &InName = Args[InIdx].second;
1301277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    genTypeCheck(InTypes[InIdx], InName.c_str());
1302277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (InIdx > 0)
1303277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      genPairwiseDimCheck(In0Name.c_str(), InName.c_str());
1304277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1305277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Create a temporary output allocation
1306277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const char OutputAllocName[] = "aout";
1307277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const size_t OutputAllocLength =
1308277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      ResultType->getClass() == RSExportType::ExportClassConstantArray
1309277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      ? static_cast<const RSExportConstantArrayType *>(ResultType)->getNumElement()
1310277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      : 1;
1311277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << "Allocation " << OutputAllocName << " = Allocation.createSized("
1312277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                << SAVED_RS_REFERENCE << ", "
1313277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                << RS_ELEM_PREFIX << ResultType->getElementName() << ", "
1314277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                << OutputAllocLength << ");\n";
1315277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << OutputAllocName << ".setAutoPadding(true);\n";
1316277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // Call the underlying reduce entry point
13171c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  mOut.indent() << "reduce(" << RS_EXPORT_REDUCE_INDEX_PREFIX << ER->getNameReduce()
1318277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                << ", new Allocation[]{" << In0Name;
1319277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (size_t InIdx = 1, InEnd = Ins.size(); InIdx < InEnd; ++InIdx)
1320277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut << ", " << Args[InIdx].second;
1321277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut << "}, " << OutputAllocName << ", " << FormalOptionsName << ");\n";
1322277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << "return new " << ResultTypeName << "(" << OutputAllocName << ");\n";
1323277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  endFunction();
1324277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1325277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1326277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Grossnamespace {
1327277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1328277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// When we've copied the Allocation to a Java array, how do we
1329277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// further process the elements of that array?
1330277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Grossenum MapFromAllocation {
1331277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  MapFromAllocationTrivial,  // no further processing
1332277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  MapFromAllocationPositive, // need to ensure elements are positive (range check)
1333277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  MapFromAllocationBoolean,  // need to convert elements from byte to boolean
1334277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  MapFromAllocationPromote   // need to zero extend elements
1335277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross};
1336277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1337277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// Return Java expression that maps from an Allocation element to a Java non-vector result.
1338277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//
1339277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// MFA                     = mapping kind
1340277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// ArrayElementTypeName    = type of InVal (having been copied out of Allocation to Java array)
1341277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// ReflectedScalarTypeName = type of mapped value
1342277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// InVal                   = input value that must be mapped
1343277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//
13441c6bf88e098c767c3cd445f2c2514f0598d91501David Grossstd::string genReduceResultMapping(MapFromAllocation MFA,
13451c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                   const std::string &ArrayElementTypeName,
13461c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                   const std::string &ReflectedScalarTypeName,
13471c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                   const char *InVal) {
1348277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  switch (MFA) {
1349277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    default:
1350277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      slangAssert(!"Unknown MapFromAllocation");
1351277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      // and fall through
1352277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    case MapFromAllocationPositive: // range checking must be done separately
1353277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    case MapFromAllocationTrivial:
1354277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      return InVal;
1355277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    case MapFromAllocationBoolean:
1356277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      return std::string(InVal) + std::string(" != 0");
1357277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    case MapFromAllocationPromote:
1358277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      return ZeroExtendValue(InVal,
1359277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                             ArrayElementTypeName,
1360277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                             ReflectedScalarTypeName);
1361277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1362277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1363277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1364277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// Return Java expression that maps from an Allocation element to a Java vector result.
1365277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//
1366277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// MFA                     = mapping kind
1367277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// ArrayElementTypeName    = type of InVal (having been copied out of Allocation to Java array)
1368277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// ReflectedScalarTypeName = type of mapped value
1369277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// VectorTypeName          = type of vector
1370277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// VectorElementCount      = number of elements in the vector
1371277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// InArray                 = input array containing vector elements
1372277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross// InIdx                   = index of first vector element within InArray (or nullptr, if 0)
1373277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//
13741c6bf88e098c767c3cd445f2c2514f0598d91501David Grossstd::string genReduceResultVectorMapping(MapFromAllocation MFA,
13751c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                         const std::string &ArrayElementTypeName,
13761c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                         const std::string &ReflectedScalarTypeName,
13771c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                         const std::string &VectorTypeName,
13781c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                         unsigned VectorElementCount,
13791c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                         const char *InArray, const char *InIdx = nullptr) {
1380277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  std::string result = "new " + VectorTypeName + "(";
1381277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  for (unsigned VectorElementIdx = 0; VectorElementIdx < VectorElementCount; ++VectorElementIdx) {
1382277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (VectorElementIdx)
1383277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross     result += ", ";
1384277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1385277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    std::string ArrayElementName = std::string(InArray) + "[";
1386277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (InIdx)
1387277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      ArrayElementName += std::string(InIdx) + "+";
1388277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    ArrayElementName += std::to_string(VectorElementIdx) + "]";
1389277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
13901c6bf88e098c767c3cd445f2c2514f0598d91501David Gross    result += genReduceResultMapping(MFA, ArrayElementTypeName, ReflectedScalarTypeName,
13911c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                     ArrayElementName.c_str());
1392277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1393277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  result += ")";
1394277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  return result;
1395277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1396277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
13971c6bf88e098c767c3cd445f2c2514f0598d91501David Grossvoid genReduceResultRangeCheck(GeneratedFile &Out, const char *InVal) {
1398277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  Out.indent() << "if (" << InVal << " < 0)\n";
1399277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  Out.indent() << "    throw new RSRuntimeException(\"Result is not representible in Java\");\n";
1400277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1401277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1402277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross} // end anonymous namespace
1403277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
14041c6bf88e098c767c3cd445f2c2514f0598d91501David Grossvoid RSReflectionJava::genExportReduceResultType(const RSExportType *ResultType) {
14051c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  if (!exportableReduce(ResultType))
1406277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    return;
1407277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
14081c6bf88e098c767c3cd445f2c2514f0598d91501David Gross  const std::string ClassName = GetReduceResultTypeName(ResultType);
14092b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  const std::string GetMethodReturnTypeName = GetTypeName(ResultType);
1410277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << "// To obtain the result, invoke get(), which blocks\n";
1411277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << "// until the asynchronously-launched operation has completed.\n";
1412277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << "public static class " << ClassName;
1413277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.startBlock();
14142b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  startFunction(AM_Public, false, GetMethodReturnTypeName.c_str(), "get", 0);
1415277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1416277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  RSReflectionTypeData TypeData;
1417277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  ResultType->convertToRTD(&TypeData);
1418277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1419277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const std::string UnbracketedResultTypeName =
1420277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      GetTypeName(ResultType, TypeNameDefault & ~TypeNameWithConstantArrayBrackets);
1421277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const std::string ReflectedScalarTypeName = TypeData.type->java_name;
1422991096ff0ab7d2dc124994c0a40290212de349bdDavid Gross  // Note: MATRIX* types do not have a java_array_element_name
1423277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  const std::string ArrayElementTypeName =
1424277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      TypeData.type->java_array_element_name
1425277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      ? std::string(TypeData.type->java_array_element_name)
1426277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      : ReflectedScalarTypeName;
1427277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1428277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  MapFromAllocation MFA = MapFromAllocationTrivial;
1429277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  if (std::string(TypeData.type->rs_type) == "UNSIGNED_64")
1430277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    MFA = MapFromAllocationPositive;
1431277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  else if (ReflectedScalarTypeName == "boolean")
1432277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    MFA = MapFromAllocationBoolean;
1433277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  else if (ReflectedScalarTypeName != ArrayElementTypeName)
1434277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    MFA = MapFromAllocationPromote;
1435277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
14362b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "if (!mGotResult)";
14372b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.startBlock();
14382b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross
1439277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  if (TypeData.vecSize == 1) { // result type is non-vector
1440277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    // <ArrayElementType>[] outArray = new <ArrayElementType>[1];
1441277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    // mOut.copyTo(outArray);
1442277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << ArrayElementTypeName << "[] outArray = new " << ArrayElementTypeName
1443277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                  << "[" << std::max(TypeData.arraySize, 1U) << "];\n";
1444277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << "mOut.copyTo(outArray);\n";
1445277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (TypeData.arraySize == 0) { // result type is non-array non-vector
14462b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      // mResult = outArray[0]; // but there are several special cases
1447277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      if (MFA == MapFromAllocationPositive)
14481c6bf88e098c767c3cd445f2c2514f0598d91501David Gross        genReduceResultRangeCheck(mOut, "outArray[0]");
14492b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      mOut.indent() << "mResult = "
14501c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                    << genReduceResultMapping(MFA, ArrayElementTypeName, ReflectedScalarTypeName,
14511c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                              "outArray[0]")
1452277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                    << ";\n";
1453277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    } else { // result type is array of non-vector
1454277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      if (MFA == MapFromAllocationTrivial) {
14552b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross        // mResult = outArray;
14562b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross        mOut.indent() << "mResult = outArray;\n";
1457277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      } else {
1458277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        // <ResultType> result = new <UnbracketedResultType>[<ArrayElementCount>];
1459277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        // for (unsigned Idx = 0; Idx < <ArrayElementCount>; ++Idx)
1460277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        //   result[Idx] = <Transform>(outArray[Idx]);
14612b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross        // mResult = result; // but there are several special cases
1462277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        if (MFA != MapFromAllocationPositive) {
1463277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross          mOut.indent() << GetTypeName(ResultType) << " result = new "
1464277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                        << UnbracketedResultTypeName
1465277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                        << "[" << TypeData.arraySize << "];\n";
1466277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        }
1467277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        mOut.indent() << "for (int Idx = 0; Idx < " << TypeData.arraySize << "; ++Idx)";
1468277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        mOut.startBlock();
1469277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        if (MFA == MapFromAllocationPositive) {
14701c6bf88e098c767c3cd445f2c2514f0598d91501David Gross          genReduceResultRangeCheck(mOut, "outArray[Idx]");
1471277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        } else {
1472277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross          mOut.indent() << "result[Idx] = "
14731c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                        << genReduceResultMapping(MFA, ArrayElementTypeName, ReflectedScalarTypeName,
1474277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                                                     "outArray[Idx]")
1475277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                        << ";\n";
1476277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        }
1477277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross        mOut.endBlock();
14782b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross        mOut.indent() << "mResult = " << (MFA == MapFromAllocationPositive ? "outArray" : "result") << ";\n";
1479277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      }
1480277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1481277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  } else { // result type is vector or array of vector
1482277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    // <ArrayElementType>[] outArray = new <ArrayElementType>[<VectorElementCount> * <ArrayElementCount>];
1483277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    // mOut.copyTo(outArray);
1484277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const unsigned VectorElementCount = TypeData.vecSize;
1485277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    const unsigned OutArrayElementCount = VectorElementCount * std::max(TypeData.arraySize, 1U);
1486277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << ArrayElementTypeName << "[] outArray = new " << ArrayElementTypeName
1487277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                  << "[" << OutArrayElementCount << "];\n";
1488277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    mOut.indent() << "mOut.copyTo(outArray);\n";
1489277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (MFA == MapFromAllocationPositive) {
1490277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.indent() << "for (int Idx = 0; Idx < " << OutArrayElementCount << "; ++Idx)";
1491277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.startBlock();
14921c6bf88e098c767c3cd445f2c2514f0598d91501David Gross      genReduceResultRangeCheck(mOut, "outArray[Idx]");
1493277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.endBlock();
1494277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1495277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    if (TypeData.arraySize == 0) { // result type is vector
14962b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      // mResult = new <ResultType>(outArray[0], outArray[1] ...); // but there are several special cases
14972b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      mOut.indent() << "mResult = "
14981c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                    << genReduceResultVectorMapping(MFA,
14991c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                                    ArrayElementTypeName, ReflectedScalarTypeName,
15001c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                                    GetTypeName(ResultType), VectorElementCount,
15011c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                                    "outArray")
1502277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                    << ";\n";
1503277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    } else { // result type is array of vector
1504277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      // <ResultType> result = new <UnbracketedResultType>[<ArrayElementCount>];
1505277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      // for (unsigned Idx = 0; Idx < <ArrayElementCount>; ++Idx)
1506277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      //   result[Idx] = new <UnbracketedResultType>(outArray[<ArrayElementCount>*Idx+0],
1507277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      //                                             outArray[<ArrayElementCount>*Idx+1]...);
15082b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      // mResult = result; // but there are several special cases
1509277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.indent() << GetTypeName(ResultType) << " result = new "
1510277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                    << UnbracketedResultTypeName
1511277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                    << "[" << TypeData.arraySize << "];\n";
1512277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.indent() << "for (int Idx = 0; Idx < " << TypeData.arraySize << "; ++Idx)";
1513277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.startBlock();
1514277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.indent() << "result[Idx] = "
15151c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                    << genReduceResultVectorMapping(MFA,
15161c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                                    ArrayElementTypeName, ReflectedScalarTypeName,
15171c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                                    UnbracketedResultTypeName, VectorElementCount,
15181c6bf88e098c767c3cd445f2c2514f0598d91501David Gross                                                    "outArray", (std::to_string(VectorElementCount) + "*Idx").c_str())
1519277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross                    << ";\n";
1520277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      mOut.endBlock();
15212b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross      mOut.indent() << "mResult = result;\n";
1522277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    }
1523277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  }
1524277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
15252b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "mOut.destroy();\n";
15262b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "mOut = null;  // make Java object eligible for garbage collection\n";
15272b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "if (mTempIns != null)";
15282b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.startBlock();
15292b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "for (Allocation tempIn : mTempIns)";
15302b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.startBlock();
15312b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "tempIn.destroy();\n";
15322b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.endBlock();
15332b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "mTempIns = null;  // make Java objects eligible for garbage collection\n";
15342b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.endBlock();
15352b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "mGotResult = true;\n";
15362b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.endBlock();
15372b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross
15382b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "return mResult;\n";
1539277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  endFunction();
15402b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross
1541277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  startFunction(AM_Private, false, nullptr, ClassName, 1, "Allocation", "out");
1542277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // TODO: Generate allocation type check and size check?  Or move
1543277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // responsibility for instantiating the Allocation here, instead of
1544277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  // the reduce_* method?
15452b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "mTempIns = null;\n";
1546277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << "mOut = out;\n";
15472b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "mGotResult = false;\n";
1548277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  endFunction();
15492b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "private Allocation[] mTempIns;\n";
1550277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.indent() << "private Allocation mOut;\n";
15512b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  // TODO: If result is reference type rather than primitive type, we
15522b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  // could omit mGotResult and use mResult==null to indicate that we
15532b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  // haven't obtained the result yet.
15542b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "private boolean mGotResult;\n";
15552b377908d8bd15fabc370547f2cc55ffc58bafd4David Gross  mOut.indent() << "private " << GetMethodReturnTypeName << " mResult;\n";
1556277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  mOut.endBlock();
1557277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross}
1558277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
1559277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross//////////////////////////////////////////////////////////////////////////////////////////////////////
1560277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
15612e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeInstanceFromPointer(const RSExportType *ET) {
156248b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  if (ET->getClass() == RSExportType::ExportClassPointer) {
15639ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    // For pointer parameters to original forEach kernels.
156448b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    const RSExportPointerType *EPT =
15652ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportPointerType *>(ET);
15662e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genTypeInstance(EPT->getPointeeType());
15679ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines  } else {
15689ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    // For handling pass-by-value kernel parameters.
15692e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genTypeInstance(ET);
1570a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines  }
1571a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines}
157248b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
15732e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeInstance(const RSExportType *ET) {
1574a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines  switch (ET->getClass()) {
15752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive:
15762ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector:
15772ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray: {
15782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::string TypeName = ET->getElementName();
15792e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    if (addTypeNameForElement(TypeName)) {
1580f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << RS_ELEM_PREFIX << TypeName << " = Element." << TypeName
1581f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << "(rs);\n";
1582a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines    }
15832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
15842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
158548b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
15862ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
15872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::string ClassName = ET->getElementName();
15882e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    if (addTypeNameForElement(ClassName)) {
1589f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << RS_ELEM_PREFIX << ClassName << " = " << ClassName
1590f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ".createElement(rs);\n";
159148b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    }
15922ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
15932ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
1594a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines
15952ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default:
15962ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
159748b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  }
159848b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines}
159948b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
16002e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genFieldPackerInstance(const RSExportType *ET) {
16011f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  switch (ET->getClass()) {
16022ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive:
16032ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector:
16042ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray:
16052ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
16062ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::string TypeName = ET->getElementName();
16072e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    addTypeNameForFieldPacker(TypeName);
16082ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
16092ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
16101f6c331d622ac645ab68a016aa4c577998547373Stephen Hines
16112ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default:
16122ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
16131f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  }
16141f6c331d622ac645ab68a016aa4c577998547373Stephen Hines}
16151f6c331d622ac645ab68a016aa4c577998547373Stephen Hines
16162e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeCheck(const RSExportType *ET,
1617602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                    const char *VarName) {
1618f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "// check " << VarName << "\n";
161948b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
162048b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  if (ET->getClass() == RSExportType::ExportClassPointer) {
162148b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    const RSExportPointerType *EPT =
16222ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportPointerType *>(ET);
162348b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    ET = EPT->getPointeeType();
162448b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  }
162548b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
162648b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  std::string TypeName;
162748b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
162848b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  switch (ET->getClass()) {
16292ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive:
16302ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector:
16312ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
16322ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    TypeName = ET->getElementName();
16332ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
16342ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
163548b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
16362ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default:
16372ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
163848b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  }
163948b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
164048b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  if (!TypeName.empty()) {
1641f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "if (!" << VarName
1642f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << ".getType().getElement().isCompatible(" RS_ELEM_PREFIX
1643f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << TypeName << ")) {\n";
1644f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "    throw new RSRuntimeException(\"Type mismatch with "
1645f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << TypeName << "!\");\n";
1646f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "}\n";
164748b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines  }
1648b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines}
1649b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
16502e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genPrimitiveTypeExportVariable(const RSExportVar *EV) {
1651602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet  slangAssert(
1652602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet      (EV->getType()->getClass() == RSExportType::ExportClassPrimitive) &&
1653602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet      "Variable should be type of primitive here");
16549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
16559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const RSExportPrimitiveType *EPT =
16562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      static_cast<const RSExportPrimitiveType *>(EV->getType());
16570d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string TypeName = GetTypeName(EPT);
1658e2ead846c1d78a6e7108e521ffd15850bd9eed3cChih-Hung Hsieh  const std::string &VarName = EV->getName();
16599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
16602e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genPrivateExportVariable(TypeName, EV->getName());
16619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
16625d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines  if (EV->isConst()) {
1663f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "public final static " << TypeName
1664f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << " " RS_EXPORT_VAR_CONST_PREFIX << VarName << " = ";
16655d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines    const clang::APValue &Val = EV->getInit();
1666efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    genInitValue(Val, EPT->getType() == DataTypeBoolean);
1667f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << ";\n";
16685d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines  } else {
16695d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines    // set_*()
16701f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    // This must remain synchronized, since multiple Dalvik threads may
16711f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    // be calling setters.
16722e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    startFunction(AM_PublicSynchronized, false, "void", "set_" + VarName, 1,
16732e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  TypeName.c_str(), "v");
1674657d20afa621219c1eed72178d1325fd4409f458David Gross    if ((EPT->getElementSizeInBytes() < 4) || EV->isUnsigned()) {
16751f6c331d622ac645ab68a016aa4c577998547373Stephen Hines      // We create/cache a per-type FieldPacker. This allows us to reuse the
16761f6c331d622ac645ab68a016aa4c577998547373Stephen Hines      // validation logic (for catching negative inputs from Dalvik, as well
16771f6c331d622ac645ab68a016aa4c577998547373Stephen Hines      // as inputs that are too large to be represented in the unsigned type).
1678bcae1fe692a8c5d9225a9699a932380b5659a735Stephen Hines      // Sub-integer types are also handled specially here, so that we don't
1679bcae1fe692a8c5d9225a9699a932380b5659a735Stephen Hines      // overwrite bytes accidentally.
16801f6c331d622ac645ab68a016aa4c577998547373Stephen Hines      std::string ElemName = EPT->getElementName();
16811f6c331d622ac645ab68a016aa4c577998547373Stephen Hines      std::string FPName;
16821f6c331d622ac645ab68a016aa4c577998547373Stephen Hines      FPName = RS_FP_PREFIX + ElemName;
1683f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << "if (" << FPName << "!= null) {\n";
1684f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.increaseIndent();
1685f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << FPName << ".reset();\n";
1686f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.decreaseIndent();
1687f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << "} else {\n";
1688f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.increaseIndent();
1689657d20afa621219c1eed72178d1325fd4409f458David Gross      mOut.indent() << FPName << " = new FieldPacker(" << EPT->getElementSizeInBytes()
1690f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ");\n";
1691f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.decreaseIndent();
1692f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << "}\n";
16932e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
16942e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genPackVarOfType(EPT, "v", FPName.c_str());
1695f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
1696f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ", " << FPName << ");\n";
16971f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    } else {
1698f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
1699f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ", v);\n";
17001f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    }
17019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
17021f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    // Dalvik update comes last, since the input may be invalid (and hence
17031f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    // throw an exception).
1704f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
1705462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
17062e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    endFunction();
17079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1708462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
17092e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetExportVariable(TypeName, VarName);
17102e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetFieldID(VarName);
1711462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
1712462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1713efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouilletvoid RSReflectionJava::genInitValue(const clang::APValue &Val, bool asBool) {
1714efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  switch (Val.getKind()) {
1715efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::Int: {
1716e2ead846c1d78a6e7108e521ffd15850bd9eed3cChih-Hung Hsieh    const llvm::APInt &api = Val.getInt();
1717efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    if (asBool) {
1718f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut << ((api.getSExtValue() == 0) ? "false" : "true");
1719efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    } else {
1720efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      // TODO: Handle unsigned correctly
1721f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut << api.getSExtValue();
1722efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      if (api.getBitWidth() > 32) {
1723f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        mOut << "L";
1724efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      }
1725efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    }
1726efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    break;
1727efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  }
1728efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
1729efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::Float: {
1730e2ead846c1d78a6e7108e521ffd15850bd9eed3cChih-Hung Hsieh    const llvm::APFloat &apf = Val.getFloat();
1731efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    llvm::SmallString<30> s;
1732efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    apf.toString(s);
1733f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << s.c_str();
1734efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) {
1735efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      if (s.count('.') == 0) {
1736f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        mOut << ".f";
1737efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      } else {
1738f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        mOut << "f";
1739efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      }
1740efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    }
1741efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    break;
1742efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  }
1743efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
1744efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::ComplexInt:
1745efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::ComplexFloat:
1746efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::LValue:
1747efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::Vector: {
1748efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    slangAssert(false && "Primitive type cannot have such kind of initializer");
1749efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    break;
1750efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  }
1751efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
1752efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  default: { slangAssert(false && "Unknown kind of initializer"); }
1753efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  }
1754efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet}
1755efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
17562e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genPointerTypeExportVariable(const RSExportVar *EV) {
17579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const RSExportType *ET = EV->getType();
17589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const RSExportType *PointeeType;
1759462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
17606e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert((ET->getClass() == RSExportType::ExportClassPointer) &&
17616e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines              "Variable should be type of pointer here");
1762462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
17632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  PointeeType = static_cast<const RSExportPointerType *>(ET)->getPointeeType();
17640d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string TypeName = GetTypeName(ET);
1765e2ead846c1d78a6e7108e521ffd15850bd9eed3cChih-Hung Hsieh  const std::string &VarName = EV->getName();
1766462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
17672e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genPrivateExportVariable(TypeName, VarName);
1768462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
176989273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang  // bind_*()
17702e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, false, "void", "bind_" + VarName, 1,
17712e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                TypeName.c_str(), "v");
1772462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1773f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
1774f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (v == null) bindAllocation(null, "
1775f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << RS_EXPORT_VAR_INDEX_PREFIX << VarName << ");\n";
1776462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1777f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  if (PointeeType->getClass() == RSExportType::ExportClassRecord) {
1778f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "else bindAllocation(v.getAllocation(), "
1779f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << RS_EXPORT_VAR_INDEX_PREFIX << VarName << ");\n";
1780f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  } else {
1781f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "else bindAllocation(v, " << RS_EXPORT_VAR_INDEX_PREFIX
1782f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << VarName << ");\n";
1783f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  }
1784462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
17852e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
1786462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
17872e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetExportVariable(TypeName, VarName);
1788462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
1789462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
17902e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genVectorTypeExportVariable(const RSExportVar *EV) {
17916e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert((EV->getType()->getClass() == RSExportType::ExportClassVector) &&
17926e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines              "Variable should be type of vector here");
17939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
17940d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string TypeName = GetTypeName(EV->getType());
17950d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string VarName = EV->getName();
17969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
17972e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genPrivateExportVariable(TypeName, VarName);
1798657d20afa621219c1eed72178d1325fd4409f458David Gross  genSetExportVariable(TypeName, EV, 1);
17992e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetExportVariable(TypeName, VarName);
18002e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetFieldID(VarName);
1801462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
1802462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
18032e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genMatrixTypeExportVariable(const RSExportVar *EV) {
18046e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert((EV->getType()->getClass() == RSExportType::ExportClassMatrix) &&
18056e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines              "Variable should be type of matrix here");
180692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
18072ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  const RSExportType *ET = EV->getType();
18080d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string TypeName = GetTypeName(ET);
1809e2ead846c1d78a6e7108e521ffd15850bd9eed3cChih-Hung Hsieh  const std::string &VarName = EV->getName();
181092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
18112e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genPrivateExportVariable(TypeName, VarName);
181292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
181392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang  // set_*()
181492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang  if (!EV->isConst()) {
18150d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines    const char *FieldPackerName = "fp";
18162e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    startFunction(AM_PublicSynchronized, false, "void", "set_" + VarName, 1,
18172e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  TypeName.c_str(), "v");
1818f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
181992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
18202e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    if (genCreateFieldPacker(ET, FieldPackerName))
18212e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genPackVarOfType(ET, "v", FieldPackerName);
1822f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "setVar(" RS_EXPORT_VAR_INDEX_PREFIX << VarName << ", "
1823f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << FieldPackerName << ");\n";
182492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
18252e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    endFunction();
182692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang  }
182792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
18282e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetExportVariable(TypeName, VarName);
18292e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetFieldID(VarName);
183092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang}
183192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
1832602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouilletvoid
18332e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc BrouilletRSReflectionJava::genConstantArrayTypeExportVariable(const RSExportVar *EV) {
1834657d20afa621219c1eed72178d1325fd4409f458David Gross  const RSExportType *const ET = EV->getType();
1835602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet  slangAssert(
1836657d20afa621219c1eed72178d1325fd4409f458David Gross      (ET->getClass() == RSExportType::ExportClassConstantArray) &&
1837602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet      "Variable should be type of constant array here");
18382e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang
18390d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string TypeName = GetTypeName(EV->getType());
18400d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string VarName = EV->getName();
18412e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang
18422e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genPrivateExportVariable(TypeName, VarName);
1843657d20afa621219c1eed72178d1325fd4409f458David Gross  genSetExportVariable(TypeName, EV, static_cast<const RSExportConstantArrayType *>(ET)->getNumElement());
18442e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetExportVariable(TypeName, VarName);
18452e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetFieldID(VarName);
18462e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang}
18472e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang
18482e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genRecordTypeExportVariable(const RSExportVar *EV) {
18496e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert((EV->getType()->getClass() == RSExportType::ExportClassRecord) &&
18506e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines              "Variable should be type of struct here");
18519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
18520d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string TypeName = GetTypeName(EV->getType());
18530d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines  std::string VarName = EV->getName();
18549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
18552e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genPrivateExportVariable(TypeName, VarName);
1856657d20afa621219c1eed72178d1325fd4409f458David Gross  genSetExportVariable(TypeName, EV, 1);
18572e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetExportVariable(TypeName, VarName);
18582e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genGetFieldID(VarName);
18590d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines}
18600d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines
18612e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genPrivateExportVariable(const std::string &TypeName,
1862602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                                const std::string &VarName) {
1863f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "private " << TypeName << " " << RS_EXPORT_VAR_PREFIX
1864f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << VarName << ";\n";
18650d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines}
18669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1867657d20afa621219c1eed72178d1325fd4409f458David Gross// Dimension = array element count; otherwise, 1.
18682e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genSetExportVariable(const std::string &TypeName,
1869657d20afa621219c1eed72178d1325fd4409f458David Gross                                            const RSExportVar *EV,
1870657d20afa621219c1eed72178d1325fd4409f458David Gross                                            unsigned Dimension) {
18719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!EV->isConst()) {
18720d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines    const char *FieldPackerName = "fp";
1873e2ead846c1d78a6e7108e521ffd15850bd9eed3cChih-Hung Hsieh    const std::string &VarName = EV->getName();
18740d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines    const RSExportType *ET = EV->getType();
18752e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    startFunction(AM_PublicSynchronized, false, "void", "set_" + VarName, 1,
18762e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  TypeName.c_str(), "v");
1877f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
18789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
18792e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    if (genCreateFieldPacker(ET, FieldPackerName))
18802e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genPackVarOfType(ET, "v", FieldPackerName);
1881a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines
1882a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines    if (mRSContext->getTargetAPI() < SLANG_JB_TARGET_API) {
1883a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines      // Legacy apps must use the old setVar() without Element/dim components.
1884f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
1885f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ", " << FieldPackerName << ");\n";
1886a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines    } else {
1887a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines      // We only have support for one-dimensional array reflection today,
1888a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines      // but the entry point (i.e. setVar()) takes an array of dimensions.
1889f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << "int []__dimArr = new int[1];\n";
1890657d20afa621219c1eed72178d1325fd4409f458David Gross      mOut.indent() << "__dimArr[0] = " << Dimension << ";\n";
1891f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
1892f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ", " << FieldPackerName << ", " << RS_ELEM_PREFIX
1893f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ET->getElementName() << ", __dimArr);\n";
1894a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines    }
18951ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
18962e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    endFunction();
18979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
18989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
1899462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
19002e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genGetExportVariable(const std::string &TypeName,
1901602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                            const std::string &VarName) {
19022e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, false, TypeName.c_str(), "get_" + VarName, 0);
1903462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1904f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return " << RS_EXPORT_VAR_PREFIX << VarName << ";\n";
1905462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
19062e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
190728d60bc2da19821af82d983902c3c78c078343c3Stephen Hines}
190828d60bc2da19821af82d983902c3c78c078343c3Stephen Hines
19092e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genGetFieldID(const std::string &VarName) {
191028d60bc2da19821af82d983902c3c78c078343c3Stephen Hines  // We only generate getFieldID_*() for non-Pointer (bind) types.
1911b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray  if (mRSContext->getTargetAPI() >= SLANG_JB_MR1_TARGET_API) {
19122e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    startFunction(AM_Public, false, "Script.FieldID", "getFieldID_" + VarName,
19132e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  0);
1914b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray
1915f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "return createFieldID(" << RS_EXPORT_VAR_INDEX_PREFIX
1916f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << VarName << ", null);\n";
1917b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray
19182e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    endFunction();
1919b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray  }
19209c631ff2e65a8fa766981c9683c3b255ce0a2388Shih-wei Liao}
19219c631ff2e65a8fa766981c9683c3b255ce0a2388Shih-wei Liao
19229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/******************* Methods to generate script class /end *******************/
19239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
19242e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletbool RSReflectionJava::genCreateFieldPacker(const RSExportType *ET,
1925602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                            const char *FieldPackerName) {
1926c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet  size_t AllocSize = ET->getAllocSize();
19279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (AllocSize > 0)
1928f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker("
1929f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << AllocSize << ");\n";
19309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  else
19319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
19329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
19339c631ff2e65a8fa766981c9683c3b255ce0a2388Shih-wei Liao}
19349c631ff2e65a8fa766981c9683c3b255ce0a2388Shih-wei Liao
19352e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genPackVarOfType(const RSExportType *ET,
1936602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                        const char *VarName,
1937602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                        const char *FieldPackerName) {
19389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  switch (ET->getClass()) {
19392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive:
19402ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector: {
1941f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << FieldPackerName << "."
1942f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << GetPackerAPIName(
1943f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                         static_cast<const RSExportPrimitiveType *>(ET)) << "("
1944f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << VarName << ");\n";
19452ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
19462ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
19472ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPointer: {
19482ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // Must reflect as type Allocation in Java
19492ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportType *PointeeType =
19502ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportPointerType *>(ET)->getPointeeType();
19512e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang
1952f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    if (PointeeType->getClass() != RSExportType::ExportClassRecord) {
1953f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << FieldPackerName << ".addI32(" << VarName
1954f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ".getPtr());\n";
1955f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    } else {
1956f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << FieldPackerName << ".addI32(" << VarName
1957f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ".getAllocation().getPtr());\n";
1958f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    }
19592ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
19602ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
19612ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassMatrix: {
1962f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << FieldPackerName << ".addMatrix(" << VarName << ");\n";
19632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
19642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
19652ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray: {
19662ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportConstantArrayType *ECAT =
19672ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportConstantArrayType *>(ET);
19682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
19692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // TODO(zonr): more elegant way. Currently, we obtain the unique index
19702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    //             variable (this method involves recursive call which means
19712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    //             we may have more than one level loop, therefore we can't
19722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    //             always use the same index variable name here) name given
19732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    //             in the for-loop from counting the '.' in @VarName.
19742ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    unsigned Level = 0;
19752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    size_t LastDotPos = 0;
19762ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::string ElementVarName(VarName);
19772ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
19782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    while (LastDotPos != std::string::npos) {
19792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      LastDotPos = ElementVarName.find_first_of('.', LastDotPos + 1);
19802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      Level++;
19812e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang    }
19822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::string IndexVarName("ct");
1983b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar    IndexVarName.append(llvm::utostr(Level));
1984462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1985f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "for (int " << IndexVarName << " = 0; " << IndexVarName
1986657d20afa621219c1eed72178d1325fd4409f458David Gross                  << " < " << ECAT->getNumElement() << "; " << IndexVarName << "++)";
1987f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.startBlock();
1988462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
19892ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    ElementVarName.append("[" + IndexVarName + "]");
19902e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genPackVarOfType(ECAT->getElementType(), ElementVarName.c_str(),
19912ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                     FieldPackerName);
1992462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1993f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.endBlock();
19942ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
19952ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
19962ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
19972ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportRecordType *ERT = static_cast<const RSExportRecordType *>(ET);
19982ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // Relative pos from now on in field packer
19992ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    unsigned Pos = 0;
20002ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
20012ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
20022ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                                  E = ERT->fields_end();
20032ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet         I != E; I++) {
20042ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      const RSExportRecordType::Field *F = *I;
20052ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      std::string FieldName;
20062ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      size_t FieldOffset = F->getOffsetInParent();
20072ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      const RSExportType *T = F->getType();
20082ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      size_t FieldStoreSize = T->getStoreSize();
20092ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      size_t FieldAllocSize = T->getAllocSize();
20102ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
20115abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes      if (VarName != nullptr)
20122ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        FieldName = VarName + ("." + F->getName());
20132ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      else
20142ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        FieldName = F->getName();
2015462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2016f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      if (FieldOffset > Pos) {
2017f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        mOut.indent() << FieldPackerName << ".skip(" << (FieldOffset - Pos)
2018f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                      << ");\n";
2019f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      }
2020462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
20212e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genPackVarOfType(F->getType(), FieldName.c_str(), FieldPackerName);
2022462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
20232ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      // There is padding in the field type
2024f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      if (FieldAllocSize > FieldStoreSize) {
2025f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        mOut.indent() << FieldPackerName << ".skip("
2026f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                      << (FieldAllocSize - FieldStoreSize) << ");\n";
2027f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      }
20282ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
20292ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      Pos = FieldOffset + FieldAllocSize;
2030462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
20312ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
20322ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // There maybe some padding after the struct
2033f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    if (ERT->getAllocSize() > Pos) {
2034f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << FieldPackerName << ".skip(" << ERT->getAllocSize() - Pos
2035f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ");\n";
2036f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    }
20372ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
20382ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
20392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default: { slangAssert(false && "Unknown class of type"); }
20409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
20419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
2042462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
20432e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genAllocateVarOfType(const RSExportType *T,
2044602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                            const std::string &VarName) {
20452e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang  switch (T->getClass()) {
20462ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive: {
20472ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // Primitive type like int in Java has its own storage once it's declared.
20482ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    //
20492ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // FIXME: Should we allocate storage for RS object?
20502ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // if (static_cast<const RSExportPrimitiveType *>(T)->isRSObjectType())
2051f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    //  mOut.indent() << VarName << " = new " << GetTypeName(T) << "();\n";
20522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
20532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
20542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPointer: {
20552ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // Pointer type is an instance of Allocation or a TypeClass whose value is
20562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // expected to be assigned by programmer later in Java program. Therefore
20572ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // we don't reflect things like [VarName] = new Allocation();
2058f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << VarName << " = null;\n";
20592ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
20602ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
20612ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray: {
20622ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportConstantArrayType *ECAT =
20632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportConstantArrayType *>(T);
20642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportType *ElementType = ECAT->getElementType();
20652ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
2066f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << VarName << " = new " << GetTypeName(ElementType) << "["
2067657d20afa621219c1eed72178d1325fd4409f458David Gross                  << ECAT->getNumElement() << "];\n";
20682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
20692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // Primitive type element doesn't need allocation code.
20702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (ElementType->getClass() != RSExportType::ExportClassPrimitive) {
2071657d20afa621219c1eed72178d1325fd4409f458David Gross      mOut.indent() << "for (int $ct = 0; $ct < " << ECAT->getNumElement()
2072f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << "; $ct++)";
2073f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.startBlock();
20742e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang
20752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      std::string ElementVarName(VarName);
20762ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      ElementVarName.append("[$ct]");
20772e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      genAllocateVarOfType(ElementType, ElementVarName);
20782e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang
2079f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.endBlock();
20802e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang    }
20812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
20822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
20832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector:
20842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassMatrix:
20852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
2086f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << VarName << " = new " << GetTypeName(T) << "();\n";
20872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
20882ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
20892e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang  }
20902e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang}
20912e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang
20922e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genNewItemBufferIfNull(const char *Index) {
2093f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME " == null) ";
2094f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << RS_TYPE_ITEM_BUFFER_NAME << " = new " << RS_TYPE_ITEM_CLASS_NAME
2095f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet       << "[getType().getX() /* count */];\n";
20965abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (Index != nullptr) {
2097f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME << "[" << Index
2098f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << "] == null) ";
2099f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << RS_TYPE_ITEM_BUFFER_NAME << "[" << Index << "] = new "
2100f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet         << RS_TYPE_ITEM_CLASS_NAME << "();\n";
2101f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  }
21029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
2103462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
21042e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genNewItemBufferPackerIfNull() {
2105f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " == null) ";
2106f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << RS_TYPE_ITEM_BUFFER_PACKER_NAME " = new FieldPacker("
21073a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray       <<  mItemSizeof << " * getType().getX()/* count */);\n";
2108462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2109462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
21109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/********************** Methods to generate type class  **********************/
21112e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletbool RSReflectionJava::genTypeClass(const RSExportRecordType *ERT,
2112602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                    std::string &ErrorMsg) {
2113a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines  std::string ClassName = ERT->getElementName();
21142e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  std::string superClassName = getRSPackageName();
2115f69e1e58cf65555c4be3f6c5c53f89eb044f1db5Tim Murray  superClassName += RS_TYPE_CLASS_SUPER_CLASS_NAME;
21169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
21172e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  if (!startClass(AM_Public, false, ClassName, superClassName.c_str(),
21182e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  ErrorMsg))
21199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
21209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
21214cc67fce91f43215d61b2695746eab102a3db516Stephen Hines  mGeneratedFileNames->push_back(ClassName);
21224cc67fce91f43215d61b2695746eab102a3db516Stephen Hines
21232e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeItemClass(ERT);
21249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
21259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Declare item buffer and item buffer packer
2126f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "private " << RS_TYPE_ITEM_CLASS_NAME << " "
2127f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << RS_TYPE_ITEM_BUFFER_NAME << "[];\n";
2128f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "private FieldPacker " << RS_TYPE_ITEM_BUFFER_PACKER_NAME
2129f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << ";\n";
2130f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "private static java.lang.ref.WeakReference<Element> "
2131f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << RS_TYPE_ELEMENT_REF_NAME
2132f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << " = new java.lang.ref.WeakReference<Element>(null);\n";
21332e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
21342e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeClassConstructor(ERT);
21352e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeClassCopyToArrayLocal(ERT);
21362e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeClassCopyToArray(ERT);
21372e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeClassItemSetter(ERT);
21382e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeClassItemGetter(ERT);
21392e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeClassComponentSetter(ERT);
21402e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeClassComponentGetter(ERT);
21412e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genTypeClassCopyAll(ERT);
214282754d87921c94e70562aa977cc92e28fc38b1d0Stephen Hines  if (!mRSContext->isCompatLib()) {
214382754d87921c94e70562aa977cc92e28fc38b1d0Stephen Hines    // Skip the resize method if we are targeting a compatibility library.
21442e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genTypeClassResize();
214582754d87921c94e70562aa977cc92e28fc38b1d0Stephen Hines  }
21469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
21472e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endClass();
21489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
21492e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  resetFieldIndex();
21502e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  clearFieldIndexMap();
215166aa299de2b5e0b0c7bfae7628e29a3961247aedZonr Chang
21529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
21539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
2154462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
21552e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeItemClass(const RSExportRecordType *ERT) {
2156f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "static public class " RS_TYPE_ITEM_CLASS_NAME;
2157f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.startBlock();
21589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
21593a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray  // Sizeof should not be exposed for 64-bit; it is not accurate
21603a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray  if (mRSContext->getTargetAPI() < 21) {
21613a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray      mOut.indent() << "public static final int sizeof = " << ERT->getAllocSize()
21623a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray                    << ";\n";
21633a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray  }
21649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
21659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Member elements
2166f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << "\n";
21679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
21682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                                FE = ERT->fields_end();
21692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       FI != FE; FI++) {
2170f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName()
2171f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << ";\n";
21729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
21739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
21749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Constructor
2175f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << "\n";
2176f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_CLASS_NAME << "()";
2177f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.startBlock();
21789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
21799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
21802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                                FE = ERT->fields_end();
21812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       FI != FE; FI++) {
21829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    const RSExportRecordType::Field *F = *FI;
21832e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genAllocateVarOfType(F->getType(), F->getName());
21849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
21859e86e1926328d9ecf3cd0922e55299db901f6469Shih-wei Liao
21869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // end Constructor
2187f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.endBlock();
2188462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
21899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // end Item class
2190f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.endBlock();
2191462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2192462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
21932e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeClassConstructor(const RSExportRecordType *ERT) {
21949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const char *RenderScriptVar = "rs";
21959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
21962e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, true, "Element", "createElement", 1, "RenderScript",
21972e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                RenderScriptVar);
2198381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams
2199e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines  // TODO(all): Fix weak-refs + multi-context issue.
2200f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  // mOut.indent() << "Element e = " << RS_TYPE_ELEMENT_REF_NAME
22012968921e1cedf85360964c5a39e1ce36c66ecd09Jean-Luc Brouillet  //            << ".get();\n";
2202f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  // mOut.indent() << "if (e != null) return e;\n";
2203c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  RSReflectionJavaElementBuilder builder("eb", ERT, RenderScriptVar, &mOut,
2204c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                                         mRSContext, this);
2205c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  builder.generate();
2206c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
2207f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return eb.create();\n";
2208f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  // mOut.indent() << "e = eb.create();\n";
2209f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  // mOut.indent() << RS_TYPE_ELEMENT_REF_NAME
22102968921e1cedf85360964c5a39e1ce36c66ecd09Jean-Luc Brouillet  //            << " = new java.lang.ref.WeakReference<Element>(e);\n";
2211f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  // mOut.indent() << "return e;\n";
22122e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
22139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2214381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // private with element
22155abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  startFunction(AM_Private, false, nullptr, getClassName(), 1, "RenderScript",
22162e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                RenderScriptVar);
2217f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
2218f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
2219f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
22202e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2221381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams
2222381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // 1D without usage
22235abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  startFunction(AM_Public, false, nullptr, getClassName(), 2, "RenderScript",
22242e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                RenderScriptVar, "int", "count");
22259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2226f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
2227f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
2228f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
22299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Call init() in super class
2230f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "init(" << RenderScriptVar << ", count);\n";
22312e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
22329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2233381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // 1D with usage
22345abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  startFunction(AM_Public, false, nullptr, getClassName(), 3, "RenderScript",
22352e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                RenderScriptVar, "int", "count", "int", "usages");
223691fe83b56e6ffabecdb1292ff3694275ef07aed9Jason Sams
2237f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
2238f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
2239f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
224091fe83b56e6ffabecdb1292ff3694275ef07aed9Jason Sams  // Call init() in super class
2241f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "init(" << RenderScriptVar << ", count, usages);\n";
22422e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
224391fe83b56e6ffabecdb1292ff3694275ef07aed9Jason Sams
2244381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // create1D with usage
22452e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, true, getClassName().c_str(), "create1D", 3,
22462e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "RenderScript", RenderScriptVar, "int", "dimX", "int",
22472e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "usages");
2248f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << getClassName() << " obj = new " << getClassName() << "("
2249f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << RenderScriptVar << ");\n";
2250f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "obj.mAllocation = Allocation.createSized("
2251f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                   "rs, obj.mElement, dimX, usages);\n";
2252f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return obj;\n";
22532e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2254381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams
2255381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // create1D without usage
22562e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, true, getClassName().c_str(), "create1D", 2,
22572e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "RenderScript", RenderScriptVar, "int", "dimX");
2258f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return create1D(" << RenderScriptVar
2259f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << ", dimX, Allocation.USAGE_SCRIPT);\n";
22602e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2261381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams
2262381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // create2D without usage
22632e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, true, getClassName().c_str(), "create2D", 3,
22642e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "RenderScript", RenderScriptVar, "int", "dimX", "int", "dimY");
2265f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return create2D(" << RenderScriptVar
2266f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << ", dimX, dimY, Allocation.USAGE_SCRIPT);\n";
22672e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2268381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams
2269381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // create2D with usage
22702e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, true, getClassName().c_str(), "create2D", 4,
22712e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "RenderScript", RenderScriptVar, "int", "dimX", "int", "dimY",
22722e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "int", "usages");
22732e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
2274f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << getClassName() << " obj = new " << getClassName() << "("
2275f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << RenderScriptVar << ");\n";
2276f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "Type.Builder b = new Type.Builder(rs, obj.mElement);\n";
2277f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "b.setX(dimX);\n";
2278f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "b.setY(dimY);\n";
2279f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "Type t = b.create();\n";
2280f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "obj.mAllocation = Allocation.createTyped(rs, t, usages);\n";
2281f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return obj;\n";
22822e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2283381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams
2284381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // createTypeBuilder
22852e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, true, "Type.Builder", "createTypeBuilder", 1,
22862e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "RenderScript", RenderScriptVar);
2287f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "Element e = createElement(" << RenderScriptVar << ");\n";
2288f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return new Type.Builder(rs, e);\n";
22892e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2290381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams
2291381e95f95d7eb14144081a1ca74f96c5e06ba089Jason Sams  // createCustom with usage
22922e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Public, true, getClassName().c_str(), "createCustom", 3,
22932e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "RenderScript", RenderScriptVar, "Type.Builder", "tb", "int",
22942e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "usages");
2295f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << getClassName() << " obj = new " << getClassName() << "("
2296f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << RenderScriptVar << ");\n";
2297f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "Type t = tb.create();\n";
2298f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (t.getElement() != obj.mElement) {\n";
2299f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "    throw new RSIllegalArgumentException("
2300f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                   "\"Type.Builder did not match expected element type.\");\n";
2301f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "}\n";
2302f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "obj.mAllocation = Allocation.createTyped(rs, t, usages);\n";
2303f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return obj;\n";
23042e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
23059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
2306462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
23072e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeClassCopyToArray(const RSExportRecordType *ERT) {
23082e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Private, false, "void", "copyToArray", 2,
23092e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                RS_TYPE_ITEM_CLASS_NAME, "i", "int", "index");
23109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
23112e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genNewItemBufferPackerIfNull();
2312f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << ".reset(index * "
23133a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray                << mItemSizeof << ");\n";
23149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2315f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "copyToArrayLocal(i, " RS_TYPE_ITEM_BUFFER_PACKER_NAME
2316f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                   ");\n";
231738eca1ad0d6bfac8f1fbf7c8360f4c18ecd205c2Alex Sakhartchouk
23182e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
231938eca1ad0d6bfac8f1fbf7c8360f4c18ecd205c2Alex Sakhartchouk}
232038eca1ad0d6bfac8f1fbf7c8360f4c18ecd205c2Alex Sakhartchouk
2321602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouilletvoid
23222e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc BrouilletRSReflectionJava::genTypeClassCopyToArrayLocal(const RSExportRecordType *ERT) {
23232e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_Private, false, "void", "copyToArrayLocal", 2,
23242e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                RS_TYPE_ITEM_CLASS_NAME, "i", "FieldPacker", "fp");
232538eca1ad0d6bfac8f1fbf7c8360f4c18ecd205c2Alex Sakhartchouk
23262e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  genPackVarOfType(ERT, "i", "fp");
23279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
23282e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
23299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
2330462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
23312e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeClassItemSetter(const RSExportRecordType *ERT) {
23322e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_PublicSynchronized, false, "void", "set", 3,
23332e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                RS_TYPE_ITEM_CLASS_NAME, "i", "int", "index", "boolean",
23342e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "copyNow");
23355abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  genNewItemBufferIfNull(nullptr);
2336f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << "[index] = i;\n";
23379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2338f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (copyNow) ";
2339f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.startBlock();
23409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2341f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "copyToArray(i, index);\n";
23423a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray  mOut.indent() << "FieldPacker fp = new FieldPacker(" << mItemSizeof << ");\n";
2343f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "copyToArrayLocal(i, fp);\n";
2344f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "mAllocation.setFromFieldPacker(index, fp);\n";
23459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
23469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // End of if (copyNow)
2347f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.endBlock();
23489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
23492e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
23509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
2351462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
23522e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeClassItemGetter(const RSExportRecordType *ERT) {
23532e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_PublicSynchronized, false, RS_TYPE_ITEM_CLASS_NAME, "get", 1,
23542e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "int", "index");
2355f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME
2356f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << " == null) return null;\n";
2357f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "return " << RS_TYPE_ITEM_BUFFER_NAME << "[index];\n";
23582e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2359462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2360462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2361602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouilletvoid
23622e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc BrouilletRSReflectionJava::genTypeClassComponentSetter(const RSExportRecordType *ERT) {
23639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
2364602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                                FE = ERT->fields_end();
2365602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet       FI != FE; FI++) {
23669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    const RSExportRecordType::Field *F = *FI;
23679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    size_t FieldOffset = F->getOffsetInParent();
2368c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet    size_t FieldStoreSize = F->getType()->getStoreSize();
23692e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    unsigned FieldIndex = getFieldIndex(F);
23709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
23712e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    startFunction(AM_PublicSynchronized, false, "void", "set_" + F->getName(),
23722e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  3, "int", "index", GetTypeName(F->getType()).c_str(), "v",
23732e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  "boolean", "copyNow");
23742e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genNewItemBufferPackerIfNull();
23752e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genNewItemBufferIfNull("index");
2376f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << "[index]." << F->getName()
2377f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << " = v;\n";
2378462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2379f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "if (copyNow) ";
2380f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.startBlock();
23812dd42ffb0679851777ec4733681816d399d5f7d3Shih-wei Liao
2382f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    if (FieldOffset > 0) {
2383f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << ".reset(index * "
23843a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray                    << mItemSizeof << " + " << FieldOffset
2385f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    << ");\n";
2386f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    } else {
2387f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << ".reset(index * "
23883a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray                    << mItemSizeof << ");\n";
2389f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    }
23902e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genPackVarOfType(F->getType(), "v", RS_TYPE_ITEM_BUFFER_PACKER_NAME);
2391462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2392f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "FieldPacker fp = new FieldPacker(" << FieldStoreSize
2393f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << ");\n";
23942e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    genPackVarOfType(F->getType(), "v", "fp");
2395f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "mAllocation.setFromFieldPacker(index, " << FieldIndex
2396f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << ", fp);\n";
2397462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
23989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // End of if (copyNow)
2399f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.endBlock();
2400462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
24012e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    endFunction();
24029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
24039c631ff2e65a8fa766981c9683c3b255ce0a2388Shih-wei Liao}
24049c631ff2e65a8fa766981c9683c3b255ce0a2388Shih-wei Liao
2405602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouilletvoid
24062e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc BrouilletRSReflectionJava::genTypeClassComponentGetter(const RSExportRecordType *ERT) {
24079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
2408602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                                FE = ERT->fields_end();
2409602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet       FI != FE; FI++) {
24109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    const RSExportRecordType::Field *F = *FI;
24112e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    startFunction(AM_PublicSynchronized, false,
24122e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  GetTypeName(F->getType()).c_str(), "get_" + F->getName(), 1,
24132e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  "int", "index");
2414f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "if (" RS_TYPE_ITEM_BUFFER_NAME << " == null) return "
2415f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << GetTypeNullValue(F->getType()) << ";\n";
2416f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut.indent() << "return " RS_TYPE_ITEM_BUFFER_NAME << "[index]."
2417f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                  << F->getName() << ";\n";
24182e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    endFunction();
24199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
24209c631ff2e65a8fa766981c9683c3b255ce0a2388Shih-wei Liao}
24219b1f50b1cab0687f2f218a924e4ff90184aebe0aShih-wei Liao
24222e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeClassCopyAll(const RSExportRecordType *ERT) {
24232e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_PublicSynchronized, false, "void", "copyAll", 0);
2424462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2425f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "for (int ct = 0; ct < " << RS_TYPE_ITEM_BUFFER_NAME
2426f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << ".length; ct++)"
2427f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << " copyToArray(" << RS_TYPE_ITEM_BUFFER_NAME
2428f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << "[ct], ct);\n";
2429f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "mAllocation.setFromFieldPacker(0, "
2430f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << RS_TYPE_ITEM_BUFFER_PACKER_NAME ");\n";
2431462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
24322e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2433462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2434462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
24352e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::genTypeClassResize() {
24362e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  startFunction(AM_PublicSynchronized, false, "void", "resize", 1, "int",
24372e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                "newSize");
24382e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
2439f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (mItemArray != null) ";
2440f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.startBlock();
2441f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "int oldSize = mItemArray.length;\n";
2442f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "int copySize = Math.min(oldSize, newSize);\n";
2443f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (newSize == oldSize) return;\n";
2444f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "Item ni[] = new Item[newSize];\n";
2445f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "System.arraycopy(mItemArray, 0, ni, 0, copySize);\n";
2446f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "mItemArray = ni;\n";
2447f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.endBlock();
2448f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "mAllocation.resize(newSize);\n";
2449f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
2450f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "if (" RS_TYPE_ITEM_BUFFER_PACKER_NAME
2451f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                   " != null) " RS_TYPE_ITEM_BUFFER_PACKER_NAME " = "
24523a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray                   "new FieldPacker(" << mItemSizeof << " * getType().getX()/* count */);\n";
24532e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
24542e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  endFunction();
2455d42a429f42fd6f272188af64f412cd604f02b365Zonr Chang}
2456d42a429f42fd6f272188af64f412cd604f02b365Zonr Chang
24579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/******************** Methods to generate type class /end ********************/
2458462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
24599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/********** Methods to create Element in Java of given record type ***********/
2460c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
2461c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc BrouilletRSReflectionJavaElementBuilder::RSReflectionJavaElementBuilder(
2462c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    const char *ElementBuilderName, const RSExportRecordType *ERT,
2463c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    const char *RenderScriptVar, GeneratedFile *Out, const RSContext *RSContext,
2464c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    RSReflectionJava *Reflection)
2465c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    : mElementBuilderName(ElementBuilderName), mERT(ERT),
2466c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      mRenderScriptVar(RenderScriptVar), mOut(Out), mPaddingFieldIndex(1),
2467c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      mRSContext(RSContext), mReflection(Reflection) {
2468c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  if (mRSContext->getTargetAPI() < SLANG_ICS_TARGET_API) {
2469c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    mPaddingPrefix = "#padding_";
2470c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  } else {
2471c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    mPaddingPrefix = "#rs_padding_";
2472c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  }
2473c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet}
2474c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
2475c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouilletvoid RSReflectionJavaElementBuilder::generate() {
2476c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  mOut->indent() << "Element.Builder " << mElementBuilderName
2477c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                 << " = new Element.Builder(" << mRenderScriptVar << ");\n";
2478c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  genAddElement(mERT, "", /* ArraySize = */ 0);
2479462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2480462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2481c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouilletvoid RSReflectionJavaElementBuilder::genAddElement(const RSExportType *ET,
2482c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                                                   const std::string &VarName,
2483c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                                                   unsigned ArraySize) {
248447aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines  std::string ElementConstruct = GetBuiltinElementConstruct(ET);
24859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
248647aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines  if (ElementConstruct != "") {
2487c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    genAddStatementStart();
2488c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    *mOut << ElementConstruct << "(" << mRenderScriptVar << ")";
2489c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    genAddStatementEnd(VarName, ArraySize);
24909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  } else {
2491c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
2492c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    switch (ET->getClass()) {
2493c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RSExportType::ExportClassPrimitive: {
24949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const RSExportPrimitiveType *EPT =
24952ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet          static_cast<const RSExportPrimitiveType *>(ET);
249647aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines      const char *DataTypeName =
249747aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines          RSExportPrimitiveType::getRSReflectionType(EPT)->rs_type;
2498c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      genAddStatementStart();
2499c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      *mOut << "Element.createUser(" << mRenderScriptVar
2500c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet            << ", Element.DataType." << DataTypeName << ")";
2501c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      genAddStatementEnd(VarName, ArraySize);
2502c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      break;
2503c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    }
2504c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RSExportType::ExportClassVector: {
2505c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      const RSExportVectorType *EVT =
2506c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet          static_cast<const RSExportVectorType *>(ET);
2507c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      const char *DataTypeName =
2508c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet          RSExportPrimitiveType::getRSReflectionType(EVT)->rs_type;
2509c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      genAddStatementStart();
2510c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      *mOut << "Element.createVector(" << mRenderScriptVar
2511c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet            << ", Element.DataType." << DataTypeName << ", "
2512c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet            << EVT->getNumElement() << ")";
2513c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      genAddStatementEnd(VarName, ArraySize);
2514c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      break;
2515c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    }
2516c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RSExportType::ExportClassPointer:
25179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Pointer type variable should be resolved in
25189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // GetBuiltinElementConstruct()
25196e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert(false && "??");
2520c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      break;
2521c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RSExportType::ExportClassMatrix:
252292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang      // Matrix type variable should be resolved
252392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang      // in GetBuiltinElementConstruct()
25246e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert(false && "??");
2525c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      break;
2526c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RSExportType::ExportClassConstantArray: {
25272e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang      const RSExportConstantArrayType *ECAT =
25282e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang          static_cast<const RSExportConstantArrayType *>(ET);
25292e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang
253089273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang      const RSExportType *ElementType = ECAT->getElementType();
253189273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang      if (ElementType->getClass() != RSExportType::ExportClassRecord) {
2532657d20afa621219c1eed72178d1325fd4409f458David Gross        genAddElement(ECAT->getElementType(), VarName, ECAT->getNumElement());
253389273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang      } else {
2534f3edb0046f0c1389f1318f8e7d4ea3ab9453d599David Gross        slangAssert((ArraySize == 0) && "Cannot reflect multidimensional array types");
2535657d20afa621219c1eed72178d1325fd4409f458David Gross        ArraySize = ECAT->getNumElement();
2536c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        genAddStatementStart();
2537f3edb0046f0c1389f1318f8e7d4ea3ab9453d599David Gross        *mOut << ElementType->getElementName() << ".createElement(" << mRenderScriptVar << ")";
2538c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        genAddStatementEnd(VarName, ArraySize);
253989273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang      }
2540c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      break;
2541c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    }
2542c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RSExportType::ExportClassRecord: {
25439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Simalar to case of RSExportType::ExportClassRecord in genPackVarOfType.
25449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      //
25456315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      // TODO(zonr): Generalize these two function such that there's no
25466315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      //             duplicated codes.
25479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const RSExportRecordType *ERT =
25482ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet          static_cast<const RSExportRecordType *>(ET);
25492ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      int Pos = 0; // relative pos from now on
25509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
25519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
25522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                                    E = ERT->fields_end();
25532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet           I != E; I++) {
25549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const RSExportRecordType::Field *F = *I;
25559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        int FieldOffset = F->getOffsetInParent();
2556c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet        const RSExportType *T = F->getType();
2557c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet        int FieldStoreSize = T->getStoreSize();
2558c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet        int FieldAllocSize = T->getAllocSize();
25599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2560c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        std::string FieldName;
25619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (!VarName.empty())
25629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldName = VarName + "." + F->getName();
25639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        else
25649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldName = F->getName();
25659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
25669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Alignment
2567c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        genAddPadding(FieldOffset - Pos);
25689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
25699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // eb.add(...)
2570c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        mReflection->addFieldIndexMapping(F);
257189273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang        if (F->getType()->getClass() != RSExportType::ExportClassRecord) {
2572c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet          genAddElement(F->getType(), FieldName, 0);
257389273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang        } else {
2574c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet          genAddStatementStart();
2575f3edb0046f0c1389f1318f8e7d4ea3ab9453d599David Gross          *mOut << F->getType()->getElementName() << ".createElement(" << mRenderScriptVar << ")";
2576c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet          genAddStatementEnd(FieldName, ArraySize);
257789273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang        }
25789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2579a9ae5ae8866d937a99601d24a922c8f3f4223f59Stephen Hines        if (mRSContext->getTargetAPI() < SLANG_ICS_TARGET_API) {
2580a9ae5ae8866d937a99601d24a922c8f3f4223f59Stephen Hines          // There is padding within the field type. This is only necessary
2581a9ae5ae8866d937a99601d24a922c8f3f4223f59Stephen Hines          // for HC-targeted APIs.
2582c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet          genAddPadding(FieldAllocSize - FieldStoreSize);
2583a9ae5ae8866d937a99601d24a922c8f3f4223f59Stephen Hines        }
25849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
25859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        Pos = FieldOffset + FieldAllocSize;
25869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
2587bd49c8ff5a35befb413de3b6d7989d257b54f057Shih-wei Liao
25889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // There maybe some padding after the struct
2589c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet      size_t RecordAllocSize = ERT->getAllocSize();
25900a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao
2591c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      genAddPadding(RecordAllocSize - Pos);
2592c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      break;
2593c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    }
2594c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    default:
25956e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert(false && "Unknown class of type");
2596c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      break;
2597b1a28e752571e744444377c89e5c256b4332dc58Shih-wei Liao    }
25989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2599462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2600462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2601c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouilletvoid RSReflectionJavaElementBuilder::genAddPadding(int PaddingSize) {
26029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  while (PaddingSize > 0) {
26032e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    const std::string &VarName = createPaddingField();
2604c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    genAddStatementStart();
26059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (PaddingSize >= 4) {
2606c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      *mOut << "Element.U32(" << mRenderScriptVar << ")";
26079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      PaddingSize -= 4;
26089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    } else if (PaddingSize >= 2) {
2609c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      *mOut << "Element.U16(" << mRenderScriptVar << ")";
26109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      PaddingSize -= 2;
26119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    } else if (PaddingSize >= 1) {
2612c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      *mOut << "Element.U8(" << mRenderScriptVar << ")";
26139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      PaddingSize -= 1;
2614462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2615c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    genAddStatementEnd(VarName, 0);
26169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2617462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2618462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2619c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouilletvoid RSReflectionJavaElementBuilder::genAddStatementStart() {
2620c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  mOut->indent() << mElementBuilderName << ".add(";
2621c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet}
2622c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
2623c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouilletvoid
2624c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc BrouilletRSReflectionJavaElementBuilder::genAddStatementEnd(const std::string &VarName,
2625c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                                                   unsigned ArraySize) {
2626c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  *mOut << ", \"" << VarName << "\"";
2627c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  if (ArraySize > 0) {
2628c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    *mOut << ", " << ArraySize;
2629c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  }
2630c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  *mOut << ");\n";
2631c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  // TODO Review incFieldIndex.  It's probably better to assign the numbers at
2632c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  // the start rather
2633c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  // than as we're generating the code.
2634c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet  mReflection->incFieldIndex();
2635c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet}
2636c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
26379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/******** Methods to create Element in Java of given record type /end ********/
2638462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
263959f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouilletbool RSReflectionJava::reflect() {
264059f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet  std::string ErrorMsg;
264159f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet  if (!genScriptClass(mScriptClassName, ErrorMsg)) {
264259f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet    std::cerr << "Failed to generate class " << mScriptClassName << " ("
26432e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet              << ErrorMsg << ")\n";
26442e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    return false;
26452e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  }
26469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
264759f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet  mGeneratedFileNames->push_back(mScriptClassName);
26489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
26492e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  // class ScriptField_<TypeName>
26502e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet  for (RSContext::const_export_type_iterator
26512e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet           TI = mRSContext->export_types_begin(),
26522e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet           TE = mRSContext->export_types_end();
26532e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet       TI != TE; TI++) {
26542e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    const RSExportType *ET = TI->getValue();
26552e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
26562e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    if (ET->getClass() == RSExportType::ExportClassRecord) {
26572e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      const RSExportRecordType *ERT =
26582e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet          static_cast<const RSExportRecordType *>(ET);
26592e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
26602e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet      if (!ERT->isArtificial() && !genTypeClass(ERT, ErrorMsg)) {
26612e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        std::cerr << "Failed to generate type class for struct '"
26622e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                  << ERT->getName() << "' (" << ErrorMsg << ")\n";
26632e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        return false;
26649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
2665462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
26669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2667462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
26689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
2669462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2670462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
26712e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletconst char *RSReflectionJava::AccessModifierStr(AccessModifier AM) {
26729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  switch (AM) {
26732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case AM_Public:
26742ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return "public";
26752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
26762ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case AM_Protected:
26772ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return "protected";
26782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
26792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case AM_Private:
26802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return "private";
26812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
26822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case AM_PublicSynchronized:
26832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return "public synchronized";
26842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
26852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default:
26862ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return "";
26872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
26889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2689462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2690462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
26912e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletbool RSReflectionJava::startClass(AccessModifier AM, bool IsStatic,
26922e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                  const std::string &ClassName,
26932e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                  const char *SuperClassName,
26942e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                  std::string &ErrorMsg) {
26958c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang  // Open file for class
2696f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  std::string FileName = ClassName + ".java";
269759f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet  if (!mOut.startFile(mOutputDirectory, FileName, mRSSourceFileName,
2698fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines                      mRSContext->getLicenseNote(), true,
2699fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines                      mRSContext->getVerbose())) {
27008c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang    return false;
2701f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  }
27029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
27039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Package
2704f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  if (!mPackageName.empty()) {
2705f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << "package " << mPackageName << ";\n";
2706f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  }
2707f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << "\n";
27089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
27099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Imports
2710f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << "import " << mRSPackageName << ".*;\n";
271144d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines  if (getEmbedBitcodeInJava()) {
2712f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << "import " << mPackageName << "."
271344d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines          << RSSlangReflectUtils::JavaBitcodeClassNameFromRSFileName(
271459f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                 mRSSourceFileName.c_str()) << ";\n";
271544d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines  } else {
2716f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << "import android.content.res.Resources;\n";
271744d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines  }
2718f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << "\n";
27199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
27209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // All reflected classes should be annotated as hidden, so that they won't
27219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // be exposed in SDK.
2722f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << "/**\n";
2723f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << " * @hide\n";
2724f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << " */\n";
27259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2726f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class "
2727f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet       << ClassName;
27285abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (SuperClassName != nullptr)
2729f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << " extends " << SuperClassName;
27309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2731f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.startBlock();
27329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
27339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mClassName = ClassName;
27349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
27359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
2736462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2737462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
27382e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::endClass() {
2739f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.endBlock();
2740f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.closeFile();
27419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  clear();
2742462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2743462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
27442e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::startTypeClass(const std::string &ClassName) {
2745f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << "public static class " << ClassName;
2746f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.startBlock();
2747462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2748462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2749f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouilletvoid RSReflectionJava::endTypeClass() { mOut.endBlock(); }
2750462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
27512e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::startFunction(AccessModifier AM, bool IsStatic,
27522e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                     const char *ReturnType,
27532e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                     const std::string &FunctionName, int Argc,
27542e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                     ...) {
27559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  ArgTy Args;
27569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  va_list vl;
27579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  va_start(vl, Argc);
2758462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
27596315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  for (int i = 0; i < Argc; i++) {
27602ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const char *ArgType = va_arg(vl, const char *);
27612ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const char *ArgName = va_arg(vl, const char *);
2762462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
27636315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    Args.push_back(std::make_pair(ArgType, ArgName));
27649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
27659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  va_end(vl);
2766462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
27679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  startFunction(AM, IsStatic, ReturnType, FunctionName, Args);
2768462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2769462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
27702e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid RSReflectionJava::startFunction(AccessModifier AM, bool IsStatic,
27712e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                     const char *ReturnType,
27722e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                     const std::string &FunctionName,
27732e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                     const ArgTy &Args) {
2774f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ")
2775f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << ((ReturnType) ? ReturnType : "") << " " << FunctionName
2776f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                << "(";
27779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
27789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  bool FirstArg = true;
27792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  for (ArgTy::const_iterator I = Args.begin(), E = Args.end(); I != E; I++) {
27809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (!FirstArg)
2781f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet      mOut << ", ";
27829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    else
27839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      FirstArg = false;
2784462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2785f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    mOut << I->first << " " << I->second;
27869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2787462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2788f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut << ")";
2789f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  mOut.startBlock();
2790462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
2791462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2792f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouilletvoid RSReflectionJava::endFunction() { mOut.endBlock(); }
2793e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
27942e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletbool RSReflectionJava::addTypeNameForElement(const std::string &TypeName) {
27951f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  if (mTypesToCheck.find(TypeName) == mTypesToCheck.end()) {
27961f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    mTypesToCheck.insert(TypeName);
27971f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    return true;
27981f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  } else {
27991f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    return false;
28001f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  }
28011f6c331d622ac645ab68a016aa4c577998547373Stephen Hines}
28021f6c331d622ac645ab68a016aa4c577998547373Stephen Hines
28032e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletbool RSReflectionJava::addTypeNameForFieldPacker(const std::string &TypeName) {
28041f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  if (mFieldPackerTypes.find(TypeName) == mFieldPackerTypes.end()) {
28051f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    mFieldPackerTypes.insert(TypeName);
28061f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    return true;
28071f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  } else {
28081f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    return false;
28091f6c331d622ac645ab68a016aa4c577998547373Stephen Hines  }
28101f6c331d622ac645ab68a016aa4c577998547373Stephen Hines}
28111f6c331d622ac645ab68a016aa4c577998547373Stephen Hines
28122ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet} // namespace slang
2813