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[] = {
13829456ca8e5994f43e65ad0a51982c5c2d0677657Pirama 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
2438ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid 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
2598ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Grossstd::string GetReduceResultTypeName(const RSExportReduce *ER) {
2608ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid 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),
3978ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid 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
4388ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  for (const RSExportType *ResultType : mRSContext->getReduceResultTypes(
439277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross           // FilterIn
4408ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross           exportableReduce,
441277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
442277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross           // Compare
443277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross           [](const RSExportType *A, const RSExportType *B)
4448ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross           { return GetReduceResultTypeName(A) < GetReduceResultTypeName(B); }))
4458ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross    genExportReduceResultType(ResultType);
4468ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  for (auto I = mRSContext->export_reduce_begin(),
4478ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross            E = mRSContext->export_reduce_end();
448277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross       I != E; ++I)
4498ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid 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 =
4768ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid 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);
5648ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross    if (!exportableReduce(RT))
565277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross      continue;
566277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
567277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross    genTypeInstance(RT);
568277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
5698ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross    const RSExportReduce::InTypeVec &InTypes = ER->getAccumulatorInTypes();
5708ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid 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
806c9454afec1649846512993d0ef65a9f868976bb4Chris Wailesvoid RSReflectionJava::genPairwiseDimCheck(std::string name0,
807c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes                                           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
935