blob: 685cfc446db306b12826c7faf31f49af5b9eca35 [file] [log] [blame]
Zonr Changc383a502010-10-12 01:52:08 +08001/*
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002 * Copyright 2010-2014, The Android Open Source Project
Zonr Changc383a502010-10-12 01:52:08 +08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
zonr6315f762010-10-05 15:35:14 +080017#include "slang_rs_reflection.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070018
Stephen Hinese639eb52010-11-08 19:27:20 -080019#include <sys/stat.h>
20
Shih-wei Liao462aefd2010-06-04 15:32:04 -070021#include <cstdarg>
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070022#include <cctype>
Stephen Hinese639eb52010-11-08 19:27:20 -080023
24#include <algorithm>
Stephen Hinesd369cda2012-02-13 12:00:03 -080025#include <sstream>
Stephen Hinese639eb52010-11-08 19:27:20 -080026#include <string>
27#include <utility>
Shih-wei Liao462aefd2010-06-04 15:32:04 -070028
zonr6315f762010-10-05 15:35:14 +080029#include "llvm/ADT/APFloat.h"
Zonr Chang89273bd2010-10-14 20:57:38 +080030#include "llvm/ADT/StringExtras.h"
zonr6315f762010-10-05 15:35:14 +080031
Raphael8d5a2f62011-02-08 00:15:05 -080032#include "os_sep.h"
zonr6315f762010-10-05 15:35:14 +080033#include "slang_rs_context.h"
34#include "slang_rs_export_var.h"
Stephen Hines593a8942011-05-10 15:29:50 -070035#include "slang_rs_export_foreach.h"
zonr6315f762010-10-05 15:35:14 +080036#include "slang_rs_export_func.h"
Matt Wala7682b662015-07-30 15:53:47 -070037#include "slang_rs_export_reduce.h"
zonr6315f762010-10-05 15:35:14 +080038#include "slang_rs_reflect_utils.h"
Stephen Hines4cc499d2011-08-24 19:06:17 -070039#include "slang_version.h"
zonr6315f762010-10-05 15:35:14 +080040
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070041#define RS_SCRIPT_CLASS_NAME_PREFIX "ScriptC_"
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070042#define RS_SCRIPT_CLASS_SUPER_CLASS_NAME "ScriptC"
Shih-wei Liao8b1d0dd2010-07-15 18:56:55 -070043
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070044#define RS_TYPE_CLASS_SUPER_CLASS_NAME ".Script.FieldBase"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070045
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070046#define RS_TYPE_ITEM_CLASS_NAME "Item"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070047
Tim Murray3a38b742014-07-02 10:41:08 -070048#define RS_TYPE_ITEM_SIZEOF_LEGACY "Item.sizeof"
49#define RS_TYPE_ITEM_SIZEOF_CURRENT "mElement.getBytesSize()"
50
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070051#define RS_TYPE_ITEM_BUFFER_NAME "mItemArray"
52#define RS_TYPE_ITEM_BUFFER_PACKER_NAME "mIOBuffer"
53#define RS_TYPE_ELEMENT_REF_NAME "mElementCache"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070054
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070055#define RS_EXPORT_VAR_INDEX_PREFIX "mExportVarIdx_"
56#define RS_EXPORT_VAR_PREFIX "mExportVar_"
57#define RS_EXPORT_VAR_ELEM_PREFIX "mExportVarElem_"
58#define RS_EXPORT_VAR_DIM_PREFIX "mExportVarDim_"
59#define RS_EXPORT_VAR_CONST_PREFIX "const_"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070060
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070061#define RS_ELEM_PREFIX "__"
Stephen Hinesa6b54142012-04-09 18:25:08 -070062
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070063#define RS_FP_PREFIX "__rs_fp_"
Stephen Hines1f6c3312012-07-03 17:23:33 -070064
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070065#define RS_RESOURCE_NAME "__rs_resource_name"
Stephen Hinesd2936932012-09-12 20:44:32 -070066
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070067#define RS_EXPORT_FUNC_INDEX_PREFIX "mExportFuncIdx_"
68#define RS_EXPORT_FOREACH_INDEX_PREFIX "mExportForEachIdx_"
Matt Wala7682b662015-07-30 15:53:47 -070069#define RS_EXPORT_REDUCE_INDEX_PREFIX "mExportReduceIdx_"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070070
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070071#define RS_EXPORT_VAR_ALLOCATION_PREFIX "mAlloction_"
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070072#define RS_EXPORT_VAR_DATA_STORAGE_PREFIX "mData_"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070073
Matt Wala7682b662015-07-30 15:53:47 -070074#define SAVED_RS_REFERENCE "mRSLocal"
75
Stephen Hinese639eb52010-11-08 19:27:20 -080076namespace slang {
Shih-wei Liao462aefd2010-06-04 15:32:04 -070077
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -070078class RSReflectionJavaElementBuilder {
79public:
80 RSReflectionJavaElementBuilder(const char *ElementBuilderName,
81 const RSExportRecordType *ERT,
82 const char *RenderScriptVar,
83 GeneratedFile *Out, const RSContext *RSContext,
84 RSReflectionJava *Reflection);
85 void generate();
86
87private:
88 void genAddElement(const RSExportType *ET, const std::string &VarName,
89 unsigned ArraySize);
90 void genAddStatementStart();
91 void genAddStatementEnd(const std::string &VarName, unsigned ArraySize);
92 void genAddPadding(int PaddingSize);
93 // TODO Will remove later due to field name information is not necessary for
94 // C-reflect-to-Java
95 std::string createPaddingField() {
96 return mPaddingPrefix + llvm::itostr(mPaddingFieldIndex++);
97 }
98
99 const char *mElementBuilderName;
100 const RSExportRecordType *mERT;
101 const char *mRenderScriptVar;
102 GeneratedFile *mOut;
103 std::string mPaddingPrefix;
104 int mPaddingFieldIndex;
105 const RSContext *mRSContext;
106 RSReflectionJava *mReflection;
107};
108
Zonr Chang92b344a2010-10-05 20:39:03 +0800109static const char *GetMatrixTypeName(const RSExportMatrixType *EMT) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700110 static const char *MatrixTypeJavaNameMap[] = {/* 2x2 */ "Matrix2f",
111 /* 3x3 */ "Matrix3f",
112 /* 4x4 */ "Matrix4f",
Zonr Chang92b344a2010-10-05 20:39:03 +0800113 };
114 unsigned Dim = EMT->getDim();
115
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700116 if ((Dim - 2) < (sizeof(MatrixTypeJavaNameMap) / sizeof(const char *)))
117 return MatrixTypeJavaNameMap[EMT->getDim() - 2];
Zonr Chang92b344a2010-10-05 20:39:03 +0800118
Stephen Hines6e6578a2011-02-07 18:05:48 -0800119 slangAssert(false && "GetMatrixTypeName : Unsupported matrix dimension");
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700120 return nullptr;
Zonr Chang92b344a2010-10-05 20:39:03 +0800121}
122
Stephen Hines6e6578a2011-02-07 18:05:48 -0800123static const char *GetVectorAccessor(unsigned Index) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700124 static const char *VectorAccessorMap[] = {/* 0 */ "x",
125 /* 1 */ "y",
126 /* 2 */ "z",
127 /* 3 */ "w",
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700128 };
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700129
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700130 slangAssert((Index < (sizeof(VectorAccessorMap) / sizeof(const char *))) &&
Stephen Hines6e6578a2011-02-07 18:05:48 -0800131 "Out-of-bound index to access vector member");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700132
133 return VectorAccessorMap[Index];
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700134}
135
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700136static const char *GetPackerAPIName(const RSExportPrimitiveType *EPT) {
zonr6315f762010-10-05 15:35:14 +0800137 static const char *PrimitiveTypePackerAPINameMap[] = {
Pirama Arumuga Nainare4dd17d2015-04-07 11:09:14 -0700138 "addF16", // DataTypeFloat16
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700139 "addF32", // DataTypeFloat32
140 "addF64", // DataTypeFloat64
141 "addI8", // DataTypeSigned8
142 "addI16", // DataTypeSigned16
143 "addI32", // DataTypeSigned32
144 "addI64", // DataTypeSigned64
145 "addU8", // DataTypeUnsigned8
146 "addU16", // DataTypeUnsigned16
147 "addU32", // DataTypeUnsigned32
148 "addU64", // DataTypeUnsigned64
149 "addBoolean", // DataTypeBoolean
150 "addU16", // DataTypeUnsigned565
151 "addU16", // DataTypeUnsigned5551
152 "addU16", // DataTypeUnsigned4444
153 "addMatrix", // DataTypeRSMatrix2x2
154 "addMatrix", // DataTypeRSMatrix3x3
155 "addMatrix", // DataTypeRSMatrix4x4
156 "addObj", // DataTypeRSElement
157 "addObj", // DataTypeRSType
158 "addObj", // DataTypeRSAllocation
159 "addObj", // DataTypeRSSampler
160 "addObj", // DataTypeRSScript
161 "addObj", // DataTypeRSMesh
162 "addObj", // DataTypeRSPath
163 "addObj", // DataTypeRSProgramFragment
164 "addObj", // DataTypeRSProgramVertex
165 "addObj", // DataTypeRSProgramRaster
166 "addObj", // DataTypeRSProgramStore
167 "addObj", // DataTypeRSFont
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700168 };
169 unsigned TypeId = EPT->getType();
170
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700171 if (TypeId < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char *)))
172 return PrimitiveTypePackerAPINameMap[EPT->getType()];
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700173
Stephen Hines6e6578a2011-02-07 18:05:48 -0800174 slangAssert(false && "GetPackerAPIName : Unknown primitive data type");
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700175 return nullptr;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700176}
177
Stephen Hinesd369cda2012-02-13 12:00:03 -0800178static std::string GetTypeName(const RSExportType *ET, bool Brackets = true) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700179 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700180 case RSExportType::ExportClassPrimitive: {
181 return RSExportPrimitiveType::getRSReflectionType(
182 static_cast<const RSExportPrimitiveType *>(ET))->java_name;
183 }
184 case RSExportType::ExportClassPointer: {
185 const RSExportType *PointeeType =
186 static_cast<const RSExportPointerType *>(ET)->getPointeeType();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700187
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700188 if (PointeeType->getClass() != RSExportType::ExportClassRecord)
189 return "Allocation";
190 else
191 return PointeeType->getElementName();
192 }
193 case RSExportType::ExportClassVector: {
194 const RSExportVectorType *EVT = static_cast<const RSExportVectorType *>(ET);
195 std::stringstream VecName;
196 VecName << EVT->getRSReflectionType(EVT)->rs_java_vector_prefix
197 << EVT->getNumElement();
198 return VecName.str();
199 }
200 case RSExportType::ExportClassMatrix: {
201 return GetMatrixTypeName(static_cast<const RSExportMatrixType *>(ET));
202 }
203 case RSExportType::ExportClassConstantArray: {
204 const RSExportConstantArrayType *CAT =
205 static_cast<const RSExportConstantArrayType *>(ET);
206 std::string ElementTypeName = GetTypeName(CAT->getElementType());
207 if (Brackets) {
208 ElementTypeName.append("[]");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700209 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700210 return ElementTypeName;
211 }
212 case RSExportType::ExportClassRecord: {
213 return ET->getElementName() + "." RS_TYPE_ITEM_CLASS_NAME;
214 }
215 default: { slangAssert(false && "Unknown class of type"); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700216 }
217
218 return "";
219}
220
Shih-wei Liaocf950c42010-10-06 03:44:40 -0700221static const char *GetTypeNullValue(const RSExportType *ET) {
222 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700223 case RSExportType::ExportClassPrimitive: {
224 const RSExportPrimitiveType *EPT =
225 static_cast<const RSExportPrimitiveType *>(ET);
226 if (EPT->isRSObjectType())
Shih-wei Liaocf950c42010-10-06 03:44:40 -0700227 return "null";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700228 else if (EPT->getType() == DataTypeBoolean)
229 return "false";
230 else
231 return "0";
232 break;
233 }
234 case RSExportType::ExportClassPointer:
235 case RSExportType::ExportClassVector:
236 case RSExportType::ExportClassMatrix:
237 case RSExportType::ExportClassConstantArray:
238 case RSExportType::ExportClassRecord: {
239 return "null";
240 break;
241 }
242 default: { slangAssert(false && "Unknown class of type"); }
Shih-wei Liaocf950c42010-10-06 03:44:40 -0700243 }
244 return "";
245}
246
Stephen Hines47aca4e2012-03-08 20:07:28 -0800247static std::string GetBuiltinElementConstruct(const RSExportType *ET) {
Zonr Chang2e1dba62010-10-05 22:20:11 +0800248 if (ET->getClass() == RSExportType::ExportClassPrimitive) {
Stephen Hinesa6b54142012-04-09 18:25:08 -0700249 return std::string("Element.") + ET->getElementName();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700250 } else if (ET->getClass() == RSExportType::ExportClassVector) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700251 const RSExportVectorType *EVT = static_cast<const RSExportVectorType *>(ET);
Jean-Luc Brouilletcec9b652014-05-14 19:33:57 -0700252 if (EVT->getType() == DataTypeFloat32) {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -0700253 if (EVT->getNumElement() == 2) {
Stephen Hines2b8fb642012-03-09 00:12:47 -0800254 return "Element.F32_2";
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -0700255 } else if (EVT->getNumElement() == 3) {
Stephen Hines2b8fb642012-03-09 00:12:47 -0800256 return "Element.F32_3";
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -0700257 } else if (EVT->getNumElement() == 4) {
Stephen Hines2b8fb642012-03-09 00:12:47 -0800258 return "Element.F32_4";
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -0700259 } else {
260 slangAssert(false && "Vectors should be size 2, 3, 4");
261 }
Jean-Luc Brouilletcec9b652014-05-14 19:33:57 -0700262 } else if (EVT->getType() == DataTypeUnsigned8) {
Stephen Hines2b8fb642012-03-09 00:12:47 -0800263 if (EVT->getNumElement() == 4)
264 return "Element.U8_4";
Shih-wei Liao324c0472010-06-21 13:15:11 -0700265 }
Zonr Chang92b344a2010-10-05 20:39:03 +0800266 } else if (ET->getClass() == RSExportType::ExportClassMatrix) {
267 const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType *>(ET);
268 switch (EMT->getDim()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700269 case 2:
270 return "Element.MATRIX_2X2";
271 case 3:
272 return "Element.MATRIX_3X3";
273 case 4:
274 return "Element.MATRIX_4X4";
275 default:
276 slangAssert(false && "Unsupported dimension of matrix");
Zonr Chang92b344a2010-10-05 20:39:03 +0800277 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700278 }
Stephen Hines47aca4e2012-03-08 20:07:28 -0800279 // RSExportType::ExportClassPointer can't be generated in a struct.
Shih-wei Liao324c0472010-06-21 13:15:11 -0700280
Stephen Hines47aca4e2012-03-08 20:07:28 -0800281 return "";
Stephen Hines48b72bf2011-06-10 15:37:27 -0700282}
283
Matt Wala7682b662015-07-30 15:53:47 -0700284// If FromIntegerType == DestIntegerType, then Value is returned.
285// Otherwise, return a Java expression that zero-extends the value
286// Value, assumed to be of type FromIntegerType, to the integer type
287// DestIntegerType.
288//
289// Intended operations:
290// byte -> {byte,int,short,long}
291// short -> {short,int,long}
292// int -> {int,long}
293// long -> long
294static std::string ZeroExtendValue(const std::string &Value,
295 const std::string &FromIntegerType,
296 const std::string &DestIntegerType) {
297#ifndef __DISABLE_ASSERTS
298 // Integer types arranged in increasing order by width
299 const std::vector<std::string> ValidTypes{"byte", "short", "int", "long"};
300 auto FromTypeLoc = std::find(ValidTypes.begin(), ValidTypes.end(), FromIntegerType);
301 auto DestTypeLoc = std::find(ValidTypes.begin(), ValidTypes.end(), DestIntegerType);
302 // Check that both types are valid.
303 slangAssert(FromTypeLoc != ValidTypes.end());
304 slangAssert(DestTypeLoc != ValidTypes.end());
305 // Check that DestIntegerType is at least as wide as FromIntegerType.
306 slangAssert(FromTypeLoc - ValidTypes.begin() <= DestTypeLoc - ValidTypes.begin());
307#endif
308
309 if (FromIntegerType == DestIntegerType) {
310 return Value;
311 }
312
313 std::string Mask, MaskLiteralType;
314 if (FromIntegerType == "byte") {
315 Mask = "0xff";
316 MaskLiteralType = "int";
317 } else if (FromIntegerType == "short") {
318 Mask = "0xffff";
319 MaskLiteralType = "int";
320 } else if (FromIntegerType == "int") {
321 Mask = "0xffffffffL";
322 MaskLiteralType = "long";
323 } else {
324 // long -> long casts should have already been handled.
325 slangAssert(false && "Unknown integer type");
326 }
327
328 // Cast the mask to the appropriate type.
329 if (MaskLiteralType != DestIntegerType) {
330 Mask = "(" + DestIntegerType + ") " + Mask;
331 }
332 return "((" + DestIntegerType + ") ((" + Value + ") & " + Mask + "))";
333}
334
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700335/********************** Methods to generate script class **********************/
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -0700336RSReflectionJava::RSReflectionJava(const RSContext *Context,
337 std::vector<std::string> *GeneratedFileNames,
338 const std::string &OutputBaseDirectory,
339 const std::string &RSSourceFileName,
340 const std::string &BitCodeFileName,
341 bool EmbedBitcodeInJava)
342 : mRSContext(Context), mPackageName(Context->getReflectJavaPackageName()),
343 mRSPackageName(Context->getRSPackageName()),
344 mOutputBaseDirectory(OutputBaseDirectory),
345 mRSSourceFileName(RSSourceFileName), mBitCodeFileName(BitCodeFileName),
346 mResourceId(RSSlangReflectUtils::JavaClassNameFromRSFileName(
347 mBitCodeFileName.c_str())),
348 mScriptClassName(RS_SCRIPT_CLASS_NAME_PREFIX +
349 RSSlangReflectUtils::JavaClassNameFromRSFileName(
350 mRSSourceFileName.c_str())),
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -0700351 mEmbedBitcodeInJava(EmbedBitcodeInJava), mNextExportVarSlot(0),
Matt Wala7682b662015-07-30 15:53:47 -0700352 mNextExportFuncSlot(0), mNextExportForEachSlot(0),
353 mNextExportReduceSlot(0), mLastError(""),
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -0700354 mGeneratedFileNames(GeneratedFileNames), mFieldIndex(0) {
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -0700355 slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames");
356 slangAssert(!mPackageName.empty() && mPackageName != "-");
357
358 mOutputDirectory = RSSlangReflectUtils::ComputePackagedPath(
359 OutputBaseDirectory.c_str(), mPackageName.c_str()) +
360 OS_PATH_SEPARATOR_STR;
Tim Murray3a38b742014-07-02 10:41:08 -0700361
362 // mElement.getBytesSize only exists on JB+
363 if (mRSContext->getTargetAPI() >= SLANG_JB_TARGET_API) {
364 mItemSizeof = RS_TYPE_ITEM_SIZEOF_CURRENT;
365 } else {
366 mItemSizeof = RS_TYPE_ITEM_SIZEOF_LEGACY;
367 }
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -0700368}
369
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700370bool RSReflectionJava::genScriptClass(const std::string &ClassName,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -0700371 std::string &ErrorMsg) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700372 if (!startClass(AM_Public, false, ClassName, RS_SCRIPT_CLASS_SUPER_CLASS_NAME,
373 ErrorMsg))
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700374 return false;
375
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700376 genScriptClassConstructor();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700377
Matt Wala7682b662015-07-30 15:53:47 -0700378 // Reflect exported variables
379 for (auto I = mRSContext->export_vars_begin(),
380 E = mRSContext->export_vars_end();
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700381 I != E; I++)
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700382 genExportVariable(*I);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700383
Matt Wala7682b662015-07-30 15:53:47 -0700384 // Reflect exported forEach functions (only available on ICS+)
Stephen Hines4cc499d2011-08-24 19:06:17 -0700385 if (mRSContext->getTargetAPI() >= SLANG_ICS_TARGET_API) {
Matt Wala7682b662015-07-30 15:53:47 -0700386 for (auto I = mRSContext->export_foreach_begin(),
387 E = mRSContext->export_foreach_end();
388 I != E; I++) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700389 genExportForEach(*I);
Matt Wala7682b662015-07-30 15:53:47 -0700390 }
Stephen Hines4a4bf922011-08-18 17:20:33 -0700391 }
Stephen Hines593a8942011-05-10 15:29:50 -0700392
Matt Wala7682b662015-07-30 15:53:47 -0700393 // Reflect exported reduce functions
394 for (auto I = mRSContext->export_reduce_begin(),
395 E = mRSContext->export_reduce_end();
396 I != E; ++I)
397 genExportReduce(*I);
398
399 // Reflect exported functions (invokable)
400 for (auto I = mRSContext->export_funcs_begin(),
401 E = mRSContext->export_funcs_end();
402 I != E; ++I)
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700403 genExportFunction(*I);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700404
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700405 endClass();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700406
407 return true;
408}
409
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700410void RSReflectionJava::genScriptClassConstructor() {
Stephen Hines4c8b6592014-05-22 20:18:45 -0700411 std::string className(RSSlangReflectUtils::JavaBitcodeClassNameFromRSFileName(
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -0700412 mRSSourceFileName.c_str()));
Stephen Hinesd2936932012-09-12 20:44:32 -0700413 // Provide a simple way to reference this object.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700414 mOut.indent() << "private static final String " RS_RESOURCE_NAME " = \""
415 << getResourceId() << "\";\n";
Stephen Hinesd2936932012-09-12 20:44:32 -0700416
417 // Generate a simple constructor with only a single parameter (the rest
418 // can be inferred from information we already have).
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700419 mOut.indent() << "// Constructor\n";
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700420 startFunction(AM_Public, false, nullptr, getClassName(), 1, "RenderScript",
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700421 "rs");
Stephen Hines44d495d2014-05-22 19:42:55 -0700422
Matt Wala7682b662015-07-30 15:53:47 -0700423 const bool haveReduceExportables =
424 mRSContext->export_reduce_begin() != mRSContext->export_reduce_end();
425
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700426 if (getEmbedBitcodeInJava()) {
Stephen Hines4c8b6592014-05-22 20:18:45 -0700427 // Call new single argument Java-only constructor
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700428 mOut.indent() << "super(rs,\n";
429 mOut.indent() << " " << RS_RESOURCE_NAME ",\n";
430 mOut.indent() << " " << className << ".getBitCode32(),\n";
Stephen Hines9ae18b22014-06-10 23:53:00 -0700431 mOut.indent() << " " << className << ".getBitCode64());\n";
Stephen Hines4c8b6592014-05-22 20:18:45 -0700432 } else {
433 // Call alternate constructor with required parameters.
434 // Look up the proper raw bitcode resource id via the context.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700435 mOut.indent() << "this(rs,\n";
436 mOut.indent() << " rs.getApplicationContext().getResources(),\n";
437 mOut.indent() << " rs.getApplicationContext().getResources()."
438 "getIdentifier(\n";
439 mOut.indent() << " " RS_RESOURCE_NAME ", \"raw\",\n";
440 mOut.indent()
441 << " rs.getApplicationContext().getPackageName()));\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700442 endFunction();
Stephen Hinesd2936932012-09-12 20:44:32 -0700443
Stephen Hines4c8b6592014-05-22 20:18:45 -0700444 // Alternate constructor (legacy) with 3 original parameters.
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700445 startFunction(AM_Public, false, nullptr, getClassName(), 3, "RenderScript",
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700446 "rs", "Resources", "resources", "int", "id");
Stephen Hines4c8b6592014-05-22 20:18:45 -0700447 // Call constructor of super class
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700448 mOut.indent() << "super(rs, resources, id);\n";
Stephen Hines4c8b6592014-05-22 20:18:45 -0700449 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700450
451 // If an exported variable has initial value, reflect it
452
Matt Wala7682b662015-07-30 15:53:47 -0700453 for (auto I = mRSContext->export_vars_begin(),
454 E = mRSContext->export_vars_end();
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700455 I != E; I++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700456 const RSExportVar *EV = *I;
Stephen Hinesd369cda2012-02-13 12:00:03 -0800457 if (!EV->getInit().isUninit()) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700458 genInitExportVariable(EV->getType(), EV->getName(), EV->getInit());
Stephen Hinesd369cda2012-02-13 12:00:03 -0800459 } else if (EV->getArraySize()) {
460 // Always create an initial zero-init array object.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700461 mOut.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = new "
462 << GetTypeName(EV->getType(), false) << "["
463 << EV->getArraySize() << "];\n";
Stephen Hinesd369cda2012-02-13 12:00:03 -0800464 size_t NumInits = EV->getNumInits();
465 const RSExportConstantArrayType *ECAT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700466 static_cast<const RSExportConstantArrayType *>(EV->getType());
Stephen Hinesd369cda2012-02-13 12:00:03 -0800467 const RSExportType *ET = ECAT->getElementType();
468 for (size_t i = 0; i < NumInits; i++) {
469 std::stringstream Name;
470 Name << EV->getName() << "[" << i << "]";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700471 genInitExportVariable(ET, Name.str(), EV->getInitArray(i));
Stephen Hinesd369cda2012-02-13 12:00:03 -0800472 }
473 }
Stephen Hinesa6b54142012-04-09 18:25:08 -0700474 if (mRSContext->getTargetAPI() >= SLANG_JB_TARGET_API) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700475 genTypeInstance(EV->getType());
Stephen Hinesa6b54142012-04-09 18:25:08 -0700476 }
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700477 genFieldPackerInstance(EV->getType());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700478 }
479
Matt Wala7682b662015-07-30 15:53:47 -0700480 if (haveReduceExportables) {
481 mOut.indent() << SAVED_RS_REFERENCE << " = rs;\n";
482 }
483
484 // Reflect argument / return types in kernels
485
486 for (auto I = mRSContext->export_foreach_begin(),
487 E = mRSContext->export_foreach_end();
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700488 I != E; I++) {
Stephen Hines48b72bf2011-06-10 15:37:27 -0700489 const RSExportForEach *EF = *I;
490
Chris Wailesc9454af2014-06-13 17:25:40 -0700491 const RSExportForEach::InTypeVec &InTypes = EF->getInTypes();
492 for (RSExportForEach::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
493 BI != EI; BI++) {
494
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700495 if (*BI != nullptr) {
Chris Wailesc9454af2014-06-13 17:25:40 -0700496 genTypeInstanceFromPointer(*BI);
497 }
Stephen Hines48b72bf2011-06-10 15:37:27 -0700498 }
Chris Wailesc9454af2014-06-13 17:25:40 -0700499
Stephen Hines48b72bf2011-06-10 15:37:27 -0700500 const RSExportType *OET = EF->getOutType();
501 if (OET) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700502 genTypeInstanceFromPointer(OET);
Stephen Hines48b72bf2011-06-10 15:37:27 -0700503 }
504 }
505
Matt Wala7682b662015-07-30 15:53:47 -0700506 for (auto I = mRSContext->export_reduce_begin(),
507 E = mRSContext->export_reduce_end();
508 I != E; I++) {
509 const RSExportReduce *ER = *I;
510 genTypeInstance(ER->getType());
511 }
512
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700513 endFunction();
Jason Samsb6902e22010-11-03 17:04:06 -0700514
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700515 for (std::set<std::string>::iterator I = mTypesToCheck.begin(),
516 E = mTypesToCheck.end();
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700517 I != E; I++) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700518 mOut.indent() << "private Element " RS_ELEM_PREFIX << *I << ";\n";
Stephen Hines48b72bf2011-06-10 15:37:27 -0700519 }
520
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700521 for (std::set<std::string>::iterator I = mFieldPackerTypes.begin(),
522 E = mFieldPackerTypes.end();
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700523 I != E; I++) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700524 mOut.indent() << "private FieldPacker " RS_FP_PREFIX << *I << ";\n";
Stephen Hines1f6c3312012-07-03 17:23:33 -0700525 }
Matt Wala7682b662015-07-30 15:53:47 -0700526
527 if (haveReduceExportables) {
528 // We save a private copy of rs in order to create temporary
529 // allocations in the reduce_* entry points.
530 mOut.indent() << "private RenderScript " << SAVED_RS_REFERENCE << ";\n";
531 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700532}
533
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700534void RSReflectionJava::genInitBoolExportVariable(const std::string &VarName,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -0700535 const clang::APValue &Val) {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800536 slangAssert(!Val.isUninit() && "Not a valid initializer");
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700537 slangAssert((Val.getKind() == clang::APValue::Int) &&
538 "Bool type has wrong initial APValue");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700539
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700540 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700541
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700542 mOut << ((Val.getInt().getSExtValue() == 0) ? "false" : "true") << ";\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700543}
544
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700545void
546RSReflectionJava::genInitPrimitiveExportVariable(const std::string &VarName,
547 const clang::APValue &Val) {
Stephen Hines5d671782012-01-31 19:32:04 -0800548 slangAssert(!Val.isUninit() && "Not a valid initializer");
549
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700550 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -0700551 genInitValue(Val, false);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700552 mOut << ";\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700553}
554
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700555void RSReflectionJava::genInitExportVariable(const RSExportType *ET,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -0700556 const std::string &VarName,
557 const clang::APValue &Val) {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800558 slangAssert(!Val.isUninit() && "Not a valid initializer");
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700559
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700560 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700561 case RSExportType::ExportClassPrimitive: {
562 const RSExportPrimitiveType *EPT =
563 static_cast<const RSExportPrimitiveType *>(ET);
564 if (EPT->getType() == DataTypeBoolean) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700565 genInitBoolExportVariable(VarName, Val);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700566 } else {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700567 genInitPrimitiveExportVariable(VarName, Val);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700568 }
569 break;
570 }
571 case RSExportType::ExportClassPointer: {
572 if (!Val.isInt() || Val.getInt().getSExtValue() != 0)
573 std::cout << "Initializer which is non-NULL to pointer type variable "
574 "will be ignored\n";
575 break;
576 }
577 case RSExportType::ExportClassVector: {
578 const RSExportVectorType *EVT = static_cast<const RSExportVectorType *>(ET);
579 switch (Val.getKind()) {
580 case clang::APValue::Int:
581 case clang::APValue::Float: {
582 for (unsigned i = 0; i < EVT->getNumElement(); i++) {
583 std::string Name = VarName + "." + GetVectorAccessor(i);
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700584 genInitPrimitiveExportVariable(Name, Val);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700585 }
586 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700587 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700588 case clang::APValue::Vector: {
589 std::stringstream VecName;
590 VecName << EVT->getRSReflectionType(EVT)->rs_java_vector_prefix
591 << EVT->getNumElement();
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700592 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new "
593 << VecName.str() << "();\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700594
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700595 unsigned NumElements = std::min(
596 static_cast<unsigned>(EVT->getNumElement()), Val.getVectorLength());
597 for (unsigned i = 0; i < NumElements; i++) {
598 const clang::APValue &ElementVal = Val.getVectorElt(i);
599 std::string Name = VarName + "." + GetVectorAccessor(i);
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700600 genInitPrimitiveExportVariable(Name, ElementVal);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700601 }
602 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700603 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700604 case clang::APValue::MemberPointer:
605 case clang::APValue::Uninitialized:
606 case clang::APValue::ComplexInt:
607 case clang::APValue::ComplexFloat:
608 case clang::APValue::LValue:
609 case clang::APValue::Array:
610 case clang::APValue::Struct:
611 case clang::APValue::Union:
612 case clang::APValue::AddrLabelDiff: {
613 slangAssert(false && "Unexpected type of value of initializer.");
614 }
615 }
616 break;
617 }
618 // TODO(zonr): Resolving initializer of a record (and matrix) type variable
619 // is complex. It cannot obtain by just simply evaluating the initializer
620 // expression.
621 case RSExportType::ExportClassMatrix:
622 case RSExportType::ExportClassConstantArray:
623 case RSExportType::ExportClassRecord: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700624#if 0
625 unsigned InitIndex = 0;
zonr6315f762010-10-05 15:35:14 +0800626 const RSExportRecordType *ERT =
627 static_cast<const RSExportRecordType*>(ET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700628
Stephen Hines6e6578a2011-02-07 18:05:48 -0800629 slangAssert((Val.getKind() == clang::APValue::Vector) &&
630 "Unexpected type of initializer for record type variable");
Shih-wei Liao9c631ff2010-09-17 11:57:29 -0700631
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700632 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName
Stephen Hinesa6b54142012-04-09 18:25:08 -0700633 << " = new " << ERT->getElementName()
Jean-Luc Brouillet29689212014-05-27 13:25:31 -0700634 << "." RS_TYPE_ITEM_CLASS_NAME"();\n";
Shih-wei Liao9c631ff2010-09-17 11:57:29 -0700635
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700636 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
637 E = ERT->fields_end();
638 I != E;
639 I++) {
640 const RSExportRecordType::Field *F = *I;
641 std::string FieldName = VarName + "." + F->getName();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700642
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700643 if (InitIndex > Val.getVectorLength())
644 break;
645
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700646 genInitPrimitiveExportVariable(FieldName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700647 Val.getVectorElt(InitIndex++));
648 }
649#endif
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700650 slangAssert(false && "Unsupported initializer for record/matrix/constant "
651 "array type variable currently");
652 break;
653 }
654 default: { slangAssert(false && "Unknown class of type"); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700655 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700656}
657
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700658void RSReflectionJava::genExportVariable(const RSExportVar *EV) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700659 const RSExportType *ET = EV->getType();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700660
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700661 mOut.indent() << "private final static int " << RS_EXPORT_VAR_INDEX_PREFIX
662 << EV->getName() << " = " << getNextExportVarSlot() << ";\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700663
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700664 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700665 case RSExportType::ExportClassPrimitive: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700666 genPrimitiveTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700667 break;
668 }
669 case RSExportType::ExportClassPointer: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700670 genPointerTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700671 break;
672 }
673 case RSExportType::ExportClassVector: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700674 genVectorTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700675 break;
676 }
677 case RSExportType::ExportClassMatrix: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700678 genMatrixTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700679 break;
680 }
681 case RSExportType::ExportClassConstantArray: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700682 genConstantArrayTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700683 break;
684 }
685 case RSExportType::ExportClassRecord: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700686 genRecordTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700687 break;
688 }
689 default: { slangAssert(false && "Unknown class of type"); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700690 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700691}
692
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700693void RSReflectionJava::genExportFunction(const RSExportFunc *EF) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700694 mOut.indent() << "private final static int " << RS_EXPORT_FUNC_INDEX_PREFIX
695 << EF->getName() << " = " << getNextExportFuncSlot() << ";\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700696
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700697 // invoke_*()
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700698 ArgTy Args;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700699
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800700 if (EF->hasParam()) {
701 for (RSExportFunc::const_param_iterator I = EF->params_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700702 E = EF->params_end();
703 I != E; I++) {
704 Args.push_back(
705 std::make_pair(GetTypeName((*I)->getType()), (*I)->getName()));
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800706 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700707 }
708
Stephen Hinesbd0a7dd2015-07-01 19:24:00 -0700709 if (mRSContext->getTargetAPI() >= SLANG_M_TARGET_API) {
Yang Nicec2a1d2014-12-02 10:23:47 -0800710 startFunction(AM_Public, false, "Script.InvokeID",
711 "getInvokeID_" + EF->getName(), 0);
712
713 mOut.indent() << "return createInvokeID(" << RS_EXPORT_FUNC_INDEX_PREFIX
714 << EF->getName() << ");\n";
715
716 endFunction();
717 }
718
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700719 startFunction(AM_Public, false, "void",
720 "invoke_" + EF->getName(/*Mangle=*/false),
721 // We are using un-mangled name since Java
722 // supports method overloading.
723 Args);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700724
725 if (!EF->hasParam()) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700726 mOut.indent() << "invoke(" << RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName()
727 << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700728 } else {
729 const RSExportRecordType *ERT = EF->getParamPacketType();
730 std::string FieldPackerName = EF->getName() + "_fp";
731
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700732 if (genCreateFieldPacker(ERT, FieldPackerName.c_str()))
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700733 genPackVarOfType(ERT, nullptr, FieldPackerName.c_str());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700734
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700735 mOut.indent() << "invoke(" << RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName()
736 << ", " << FieldPackerName << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700737 }
738
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700739 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700740}
741
Chris Wailesc9454af2014-06-13 17:25:40 -0700742void RSReflectionJava::genPairwiseDimCheck(std::string name0,
743 std::string name1) {
744
745 mOut.indent() << "// Verify dimensions\n";
746 mOut.indent() << "t0 = " << name0 << ".getType();\n";
747 mOut.indent() << "t1 = " << name1 << ".getType();\n";
748 mOut.indent() << "if ((t0.getCount() != t1.getCount()) ||\n";
749 mOut.indent() << " (t0.getX() != t1.getX()) ||\n";
750 mOut.indent() << " (t0.getY() != t1.getY()) ||\n";
751 mOut.indent() << " (t0.getZ() != t1.getZ()) ||\n";
752 mOut.indent() << " (t0.hasFaces() != t1.hasFaces()) ||\n";
753 mOut.indent() << " (t0.hasMipmaps() != t1.hasMipmaps())) {\n";
754 mOut.indent() << " throw new RSRuntimeException(\"Dimension mismatch "
755 << "between parameters " << name0 << " and " << name1
756 << "!\");\n";
757 mOut.indent() << "}\n\n";
758}
759
Matt Wala7682b662015-07-30 15:53:47 -0700760void RSReflectionJava::genNullOrEmptyArrayCheck(const std::string &ArrayName) {
761 mOut.indent() << "// Verify that \"" << ArrayName << "\" is non-null.\n";
762 mOut.indent() << "if (" << ArrayName << " == null) {\n";
763 mOut.indent() << " throw new RSIllegalArgumentException(\"Array \\\""
764 << ArrayName << "\\\" is null!\");\n";
765 mOut.indent() << "}\n";
766 mOut.indent() << "// Verify that \"" << ArrayName << "\" is non-empty.\n";
767 mOut.indent() << "if (" << ArrayName << ".length == 0) {\n";
768 mOut.indent() << " throw new RSIllegalArgumentException(\"Array \\\""
769 << ArrayName << "\\\" is zero-length!\");\n";
770 mOut.indent() << "}\n";
771}
772
773void RSReflectionJava::genVectorLengthCompatibilityCheck(const std::string &ArrayName,
774 unsigned VecSize) {
775 mOut.indent() << "// Verify that the array length is a multiple of the vector size.\n";
776 mOut.indent() << "if (" << ArrayName << ".length % " << std::to_string(VecSize)
777 << " != 0) {\n";
778 mOut.indent() << " throw new RSIllegalArgumentException(\"Array \\\"" << ArrayName
779 << "\\\" is not a multiple of " << std::to_string(VecSize)
780 << " in length!\");\n";
781 mOut.indent() << "}\n";
782}
783
784void RSReflectionJava::gen1DCheck(const std::string &Name) {
785 // TODO: Check that t0.getArrayCount() == 0, when / if this API is
786 // un-hidden.
787 mOut.indent() << "Type t0 = " << Name << ".getType();\n";
788 mOut.indent() << "// Verify " << Name << " is 1D\n";
789 mOut.indent() << "if (t0.getY() != 0 ||\n";
790 mOut.indent() << " t0.hasFaces() ||\n";
791 mOut.indent() << " t0.hasMipmaps()) {\n";
792 mOut.indent() << " throw new RSIllegalArgumentException(\"Parameter "
793 << Name << " is not 1D!\");\n";
794 mOut.indent() << "}\n\n";
795}
796
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700797void RSReflectionJava::genExportForEach(const RSExportForEach *EF) {
Stephen Hinesc17e1982012-02-22 12:30:45 -0800798 if (EF->isDummyRoot()) {
799 // Skip reflection for dummy root() kernels. Note that we have to
800 // advance the next slot number for ForEach, however.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700801 mOut.indent() << "//private final static int "
802 << RS_EXPORT_FOREACH_INDEX_PREFIX << EF->getName() << " = "
803 << getNextExportForEachSlot() << ";\n";
Stephen Hinesc17e1982012-02-22 12:30:45 -0800804 return;
805 }
806
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700807 mOut.indent() << "private final static int " << RS_EXPORT_FOREACH_INDEX_PREFIX
808 << EF->getName() << " = " << getNextExportForEachSlot()
809 << ";\n";
Stephen Hines593a8942011-05-10 15:29:50 -0700810
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700811 // forEach_*()
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700812 ArgTy Args;
David Grossfb78d4c2015-03-31 13:56:05 -0700813 bool HasAllocation = false; // at least one in/out allocation?
Stephen Hines593a8942011-05-10 15:29:50 -0700814
Chris Wailesc9454af2014-06-13 17:25:40 -0700815 const RSExportForEach::InVec &Ins = EF->getIns();
816 const RSExportForEach::InTypeVec &InTypes = EF->getInTypes();
817 const RSExportType *OET = EF->getOutType();
818
819 if (Ins.size() == 1) {
David Grossfb78d4c2015-03-31 13:56:05 -0700820 HasAllocation = true;
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700821 Args.push_back(std::make_pair("Allocation", "ain"));
Chris Wailesc9454af2014-06-13 17:25:40 -0700822
823 } else if (Ins.size() > 1) {
David Grossfb78d4c2015-03-31 13:56:05 -0700824 HasAllocation = true;
Chris Wailesc9454af2014-06-13 17:25:40 -0700825 for (RSExportForEach::InIter BI = Ins.begin(), EI = Ins.end(); BI != EI;
826 BI++) {
827
828 Args.push_back(std::make_pair("Allocation",
829 "ain_" + (*BI)->getName().str()));
830 }
831 }
832
David Grossfb78d4c2015-03-31 13:56:05 -0700833 if (EF->hasOut() || EF->hasReturn()) {
834 HasAllocation = true;
Stephen Hines593a8942011-05-10 15:29:50 -0700835 Args.push_back(std::make_pair("Allocation", "aout"));
David Grossfb78d4c2015-03-31 13:56:05 -0700836 }
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700837
838 const RSExportRecordType *ERT = EF->getParamPacketType();
839 if (ERT) {
840 for (RSExportForEach::const_param_iterator I = EF->params_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700841 E = EF->params_end();
842 I != E; I++) {
843 Args.push_back(
844 std::make_pair(GetTypeName((*I)->getType()), (*I)->getName()));
Stephen Hines593a8942011-05-10 15:29:50 -0700845 }
846 }
847
Tim Murrayb81a9932012-10-10 15:56:02 -0700848 if (mRSContext->getTargetAPI() >= SLANG_JB_MR1_TARGET_API) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700849 startFunction(AM_Public, false, "Script.KernelID",
850 "getKernelID_" + EF->getName(), 0);
Tim Murrayb81a9932012-10-10 15:56:02 -0700851
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700852 // TODO: add element checking
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700853 mOut.indent() << "return createKernelID(" << RS_EXPORT_FOREACH_INDEX_PREFIX
Chris Wailesc9454af2014-06-13 17:25:40 -0700854 << EF->getName() << ", " << EF->getSignatureMetadata()
855 << ", null, null);\n";
Tim Murrayb81a9932012-10-10 15:56:02 -0700856
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700857 endFunction();
Tim Murrayb81a9932012-10-10 15:56:02 -0700858 }
859
Stephen Hines50974742013-02-12 22:11:08 -0800860 if (mRSContext->getTargetAPI() >= SLANG_JB_MR2_TARGET_API) {
David Grossfb78d4c2015-03-31 13:56:05 -0700861 if (HasAllocation) {
862 startFunction(AM_Public, false, "void", "forEach_" + EF->getName(), Args);
Stephen Hines50974742013-02-12 22:11:08 -0800863
David Grossfb78d4c2015-03-31 13:56:05 -0700864 mOut.indent() << "forEach_" << EF->getName();
865 mOut << "(";
Stephen Hines50974742013-02-12 22:11:08 -0800866
David Grossfb78d4c2015-03-31 13:56:05 -0700867 if (Ins.size() == 1) {
868 mOut << "ain, ";
Chris Wailesc9454af2014-06-13 17:25:40 -0700869
David Grossfb78d4c2015-03-31 13:56:05 -0700870 } else if (Ins.size() > 1) {
871 for (RSExportForEach::InIter BI = Ins.begin(), EI = Ins.end(); BI != EI;
872 BI++) {
Chris Wailesc9454af2014-06-13 17:25:40 -0700873
David Grossfb78d4c2015-03-31 13:56:05 -0700874 mOut << "ain_" << (*BI)->getName().str() << ", ";
875 }
Chris Wailesc9454af2014-06-13 17:25:40 -0700876 }
David Grossfb78d4c2015-03-31 13:56:05 -0700877
878 if (EF->hasOut() || EF->hasReturn()) {
879 mOut << "aout, ";
880 }
881
882 if (EF->hasUsrData()) {
883 mOut << Args.back().second << ", ";
884 }
885
886 // No clipped bounds to pass in.
887 mOut << "null);\n";
888
889 endFunction();
Stephen Hines50974742013-02-12 22:11:08 -0800890 }
891
Stephen Hines50974742013-02-12 22:11:08 -0800892 // Add the clipped kernel parameters to the Args list.
893 Args.push_back(std::make_pair("Script.LaunchOptions", "sc"));
894 }
895
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700896 startFunction(AM_Public, false, "void", "forEach_" + EF->getName(), Args);
Stephen Hines593a8942011-05-10 15:29:50 -0700897
Chris Wailesc9454af2014-06-13 17:25:40 -0700898 if (InTypes.size() == 1) {
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700899 if (InTypes.front() != nullptr) {
Chris Wailesc9454af2014-06-13 17:25:40 -0700900 genTypeCheck(InTypes.front(), "ain");
901 }
902
903 } else if (InTypes.size() > 1) {
904 size_t Index = 0;
905 for (RSExportForEach::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
906 BI != EI; BI++, ++Index) {
907
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700908 if (*BI != nullptr) {
Chris Wailesc9454af2014-06-13 17:25:40 -0700909 genTypeCheck(*BI, ("ain_" + Ins[Index]->getName()).str().c_str());
910 }
911 }
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700912 }
Chris Wailesc9454af2014-06-13 17:25:40 -0700913
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700914 if (OET) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700915 genTypeCheck(OET, "aout");
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700916 }
917
Chris Wailesc9454af2014-06-13 17:25:40 -0700918 if (Ins.size() == 1 && (EF->hasOut() || EF->hasReturn())) {
919 mOut.indent() << "Type t0, t1;";
920 genPairwiseDimCheck("ain", "aout");
921
922 } else if (Ins.size() > 1) {
923 mOut.indent() << "Type t0, t1;";
924
925 std::string In0Name = "ain_" + Ins[0]->getName().str();
926
927 for (size_t index = 1; index < Ins.size(); ++index) {
928 genPairwiseDimCheck(In0Name, "ain_" + Ins[index]->getName().str());
929 }
930
931 if (EF->hasOut() || EF->hasReturn()) {
932 genPairwiseDimCheck(In0Name, "aout");
933 }
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700934 }
935
936 std::string FieldPackerName = EF->getName() + "_fp";
937 if (ERT) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700938 if (genCreateFieldPacker(ERT, FieldPackerName.c_str())) {
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700939 genPackVarOfType(ERT, nullptr, FieldPackerName.c_str());
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700940 }
Stephen Hines593a8942011-05-10 15:29:50 -0700941 }
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700942 mOut.indent() << "forEach(" << RS_EXPORT_FOREACH_INDEX_PREFIX
943 << EF->getName();
Stephen Hines593a8942011-05-10 15:29:50 -0700944
Chris Wailesc9454af2014-06-13 17:25:40 -0700945 if (Ins.size() == 1) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700946 mOut << ", ain";
Chris Wailesc9454af2014-06-13 17:25:40 -0700947 } else if (Ins.size() > 1) {
948 mOut << ", new Allocation[]{ain_" << Ins[0]->getName().str();
949
950 for (size_t index = 1; index < Ins.size(); ++index) {
951 mOut << ", ain_" << Ins[index]->getName().str();
952 }
953
954 mOut << "}";
955
956 } else {
957 mOut << ", (Allocation) null";
958 }
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700959
Stephen Hines9ca96e72012-09-13 16:57:06 -0700960 if (EF->hasOut() || EF->hasReturn())
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700961 mOut << ", aout";
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700962 else
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700963 mOut << ", null";
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700964
965 if (EF->hasUsrData())
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700966 mOut << ", " << FieldPackerName;
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700967 else
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700968 mOut << ", null";
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700969
Stephen Hines50974742013-02-12 22:11:08 -0800970 if (mRSContext->getTargetAPI() >= SLANG_JB_MR2_TARGET_API) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700971 mOut << ", sc);\n";
Stephen Hines50974742013-02-12 22:11:08 -0800972 } else {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700973 mOut << ");\n";
Stephen Hines50974742013-02-12 22:11:08 -0800974 }
Stephen Hines593a8942011-05-10 15:29:50 -0700975
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700976 endFunction();
Stephen Hines593a8942011-05-10 15:29:50 -0700977}
978
Matt Wala7682b662015-07-30 15:53:47 -0700979void RSReflectionJava::genExportReduce(const RSExportReduce *ER) {
980 // Generate the reflected function index.
981 mOut.indent() << "private final static int " << RS_EXPORT_REDUCE_INDEX_PREFIX
982 << ER->getName() << " = " << getNextExportReduceSlot()
983 << ";\n";
984
985 // Two variants of reduce_* entry points get generated:
986 // Array variant:
987 // ty' reduce_foo(ty[] input)
988 // ty' reduce_foo(ty[] input, int x1, int x2)
989 // Allocation variant:
990 // void reduce_foo(Allocation ain, Allocation aout)
991 // void reduce_foo(Allocation ain, Allocation aout, Script.LaunchOptions sc)
992
993 const RSExportType *Type = ER->getType();
994 const std::string Name = ER->getName();
995
996 genExportReduceArrayVariant(Type, Name);
997 genExportReduceAllocationVariant(Type, Name);
998}
999
1000void RSReflectionJava::genExportReduceAllocationVariant(const RSExportType *Type,
1001 const std::string &KernelName) {
1002 const std::string FuncName = "reduce_" + KernelName;
1003
1004 // void reduce_foo(Allocation ain, Allocation aout)
1005 startFunction(AM_Public, false, "void", FuncName, 2,
1006 "Allocation", "ain",
1007 "Allocation", "aout");
1008 mOut.indent() << FuncName << "(ain, aout, null);\n";
1009 endFunction();
1010
1011 // void reduce_foo(Allocation ain, Allocation aout, Script.LaunchOptions sc)
1012 startFunction(AM_Public, false, "void", FuncName, 3,
1013 "Allocation", "ain",
1014 "Allocation", "aout",
1015 "Script.LaunchOptions", "sc");
1016
1017 // Type checking
1018 genTypeCheck(Type, "ain");
1019 genTypeCheck(Type, "aout");
1020
1021 // Check that the input is 1D
1022 gen1DCheck("ain");
1023
1024 // Call backend
1025
1026 // Script.reduce has the signature
1027 //
1028 // protected void
1029 // reduce(int slot, Allocation ain, Allocation aout, Script.LaunchOptions sc)
1030 mOut.indent() << "reduce("
1031 << RS_EXPORT_REDUCE_INDEX_PREFIX << KernelName
1032 << ", ain, aout, sc);\n";
1033
1034 endFunction();
1035}
1036
1037void RSReflectionJava::genExportReduceArrayVariant(const RSExportType *Type,
1038 const std::string &KernelName) {
1039 // Determine if the array variant can be generated. Some type
1040 // classes cannot be reflected in Java.
1041 auto Class = Type->getClass();
1042 if (Class != RSExportType::ExportClassPrimitive &&
1043 Class != RSExportType::ExportClassVector) {
1044 return;
1045 }
1046
1047 RSReflectionTypeData TypeData;
1048 Type->convertToRTD(&TypeData);
1049
1050 // Check if the type supports reading back from an Allocation and
1051 // returning as a first class Java type. If not, the helper cannot
1052 // be generated.
1053 if (!TypeData.type->java_name || !TypeData.type->java_array_element_name ||
1054 (TypeData.vecSize > 1 && !TypeData.type->rs_java_vector_prefix)) {
1055 return;
1056 }
1057
1058 const std::string FuncName = "reduce_" + KernelName;
1059 const std::string TypeName = GetTypeName(Type);
1060 const std::string ReflectedScalarType = TypeData.type->java_name;
1061 const std::string ArrayElementType = TypeData.type->java_array_element_name;
1062 const std::string ArrayType = ArrayElementType + "[]";
1063 const std::string ElementName = Type->getElementName();
1064
1065 const uint32_t VecSize = TypeData.vecSize;
1066
1067 std::string InLength = "in.length";
1068 // Adjust the length so that it corresponds to the number of
1069 // elements in the allocation.
1070 if (VecSize > 1) {
1071 InLength += " / " + std::to_string(VecSize);
1072 }
1073
1074 // TypeName reduce_foo(ArrayElementType[] in)
1075 startFunction(AM_Public, false, TypeName.c_str(), FuncName, 1,
1076 ArrayType.c_str(), "in");
1077 genNullOrEmptyArrayCheck("in");
1078 if (VecSize > 1) {
1079 genVectorLengthCompatibilityCheck("in", VecSize);
1080 }
1081 mOut.indent() << "return " << FuncName << "(in, 0, "
1082 << InLength << ");\n";
1083 endFunction();
1084
1085 // TypeName reduce_foo(ArrayElementType[] in, int x1, int x2)
1086
1087 startFunction(AM_Public, false, TypeName.c_str(), FuncName, 3,
1088 ArrayType.c_str(), "in",
1089 "int", "x1",
1090 "int", "x2");
1091
1092 genNullOrEmptyArrayCheck("in");
1093 if (VecSize > 1) {
1094 genVectorLengthCompatibilityCheck("in", VecSize);
1095 }
1096 // Check that 0 <= x1 and x1 < x2 and x2 <= InLength
1097 mOut.indent() << "// Bounds check passed x1 and x2\n";
1098 mOut.indent() << "if (x1 < 0 || x1 >= x2 || x2 > " << InLength << ") {\n";
1099 mOut.indent() << " throw new RSRuntimeException("
1100 << "\"Input bounds are invalid!\");\n";
1101 mOut.indent() << "}\n";
1102
1103 // Create a temporary input allocation.
1104 mOut.indent() << "Allocation ain = Allocation.createSized("
1105 << SAVED_RS_REFERENCE << ", "
1106 << RS_ELEM_PREFIX << ElementName << ", "
1107 << "x2 - x1);\n";
1108 mOut.indent() << "ain.setAutoPadding(true);\n";
1109 mOut.indent() << "ain.copy1DRangeFrom(x1, x2 - x1, in);\n";
1110
1111 // Create a temporary output allocation.
1112 mOut.indent() << "Allocation aout = Allocation.createSized("
1113 << SAVED_RS_REFERENCE << ", "
1114 << RS_ELEM_PREFIX << ElementName << ", "
1115 << "1);\n";
1116 mOut.indent() << "aout.setAutoPadding(true);\n";
1117
1118 mOut.indent() << FuncName << "(ain, aout, null);\n";
1119
1120 if (VecSize > 1) {
1121 // An allocation with vector elements is represented as an array
1122 // of primitives, so we have to extract the output from the
1123 // element array and rebuild the vector.
1124 //
1125 // E.g. for int2
1126 //
1127 // Allocation outArray = new int[2];
1128 // aout.copyTo(outArray);
1129 // int elem0 = outArray[0];
1130 // int elem1 = outArray[1];
1131 // return new Int2(elem0, elem1);
1132
1133 mOut.indent() << ArrayType << " outArray = new "
1134 << ArrayElementType << "[" << VecSize << "];\n";
1135
1136 mOut.indent() << "aout.copy1DRangeTo(0, 1, outArray);\n";
1137
1138 for (unsigned Elem = 0; Elem < VecSize; ++Elem) {
1139 mOut.indent() << ReflectedScalarType << " elem" << Elem << " = ";
1140 std::string Index = "outArray[" + std::to_string(Elem) + "]";
1141
1142 if (ReflectedScalarType == ArrayElementType) {
1143 mOut << Index << ";\n";
1144 } else {
1145 mOut << ZeroExtendValue(Index, ArrayElementType, ReflectedScalarType) << ";\n";
1146 }
1147 }
1148
1149 mOut.indent() << "return new " << TypeName << "(";
1150 for (unsigned Elem = 0; Elem < VecSize; ++Elem) {
1151 if (Elem > 0) mOut << ", ";
1152 mOut << "elem" << Elem;
1153 }
1154 mOut << ");\n";
1155 } else {
1156 // Scalar handling.
1157 //
1158 // E.g. for int
1159 // Allocation outArray = new int[1];
1160 // aout.copyTo(outArray);
1161 // return outArray[0];
1162 mOut.indent() << ArrayType << " outArray = new " << ArrayElementType
1163 << "[1];\n";
1164 mOut.indent() << "aout.copyTo(outArray);\n";
1165
1166 if (ReflectedScalarType == "boolean") {
1167 mOut.indent() << "return outArray[0] != 0;\n";
1168 } else if (ReflectedScalarType == ArrayElementType) {
1169 mOut.indent() << "return outArray[0];\n";
1170 } else {
1171 mOut.indent() << "return "
1172 << ZeroExtendValue("outArray[0]",
1173 ArrayElementType,
1174 ReflectedScalarType)
1175 << ";\n";
1176 }
1177 }
1178
1179 endFunction();
1180}
1181
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001182void RSReflectionJava::genTypeInstanceFromPointer(const RSExportType *ET) {
Stephen Hines48b72bf2011-06-10 15:37:27 -07001183 if (ET->getClass() == RSExportType::ExportClassPointer) {
Stephen Hines9ca96e72012-09-13 16:57:06 -07001184 // For pointer parameters to original forEach kernels.
Stephen Hines48b72bf2011-06-10 15:37:27 -07001185 const RSExportPointerType *EPT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001186 static_cast<const RSExportPointerType *>(ET);
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001187 genTypeInstance(EPT->getPointeeType());
Stephen Hines9ca96e72012-09-13 16:57:06 -07001188 } else {
1189 // For handling pass-by-value kernel parameters.
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001190 genTypeInstance(ET);
Stephen Hinesa6b54142012-04-09 18:25:08 -07001191 }
1192}
Stephen Hines48b72bf2011-06-10 15:37:27 -07001193
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001194void RSReflectionJava::genTypeInstance(const RSExportType *ET) {
Stephen Hinesa6b54142012-04-09 18:25:08 -07001195 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001196 case RSExportType::ExportClassPrimitive:
1197 case RSExportType::ExportClassVector:
1198 case RSExportType::ExportClassConstantArray: {
1199 std::string TypeName = ET->getElementName();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001200 if (addTypeNameForElement(TypeName)) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001201 mOut.indent() << RS_ELEM_PREFIX << TypeName << " = Element." << TypeName
1202 << "(rs);\n";
Stephen Hines48b72bf2011-06-10 15:37:27 -07001203 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001204 break;
1205 }
Stephen Hinesa6b54142012-04-09 18:25:08 -07001206
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001207 case RSExportType::ExportClassRecord: {
1208 std::string ClassName = ET->getElementName();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001209 if (addTypeNameForElement(ClassName)) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001210 mOut.indent() << RS_ELEM_PREFIX << ClassName << " = " << ClassName
1211 << ".createElement(rs);\n";
Stephen Hinesa6b54142012-04-09 18:25:08 -07001212 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001213 break;
1214 }
Stephen Hinesa6b54142012-04-09 18:25:08 -07001215
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001216 default:
1217 break;
Stephen Hines48b72bf2011-06-10 15:37:27 -07001218 }
1219}
1220
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001221void RSReflectionJava::genFieldPackerInstance(const RSExportType *ET) {
Stephen Hines1f6c3312012-07-03 17:23:33 -07001222 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001223 case RSExportType::ExportClassPrimitive:
1224 case RSExportType::ExportClassVector:
1225 case RSExportType::ExportClassConstantArray:
1226 case RSExportType::ExportClassRecord: {
1227 std::string TypeName = ET->getElementName();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001228 addTypeNameForFieldPacker(TypeName);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001229 break;
1230 }
Stephen Hines1f6c3312012-07-03 17:23:33 -07001231
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001232 default:
1233 break;
Stephen Hines1f6c3312012-07-03 17:23:33 -07001234 }
1235}
1236
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001237void RSReflectionJava::genTypeCheck(const RSExportType *ET,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001238 const char *VarName) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001239 mOut.indent() << "// check " << VarName << "\n";
Stephen Hines48b72bf2011-06-10 15:37:27 -07001240
1241 if (ET->getClass() == RSExportType::ExportClassPointer) {
1242 const RSExportPointerType *EPT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001243 static_cast<const RSExportPointerType *>(ET);
Stephen Hines48b72bf2011-06-10 15:37:27 -07001244 ET = EPT->getPointeeType();
1245 }
1246
1247 std::string TypeName;
1248
1249 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001250 case RSExportType::ExportClassPrimitive:
1251 case RSExportType::ExportClassVector:
1252 case RSExportType::ExportClassRecord: {
1253 TypeName = ET->getElementName();
1254 break;
1255 }
Stephen Hines48b72bf2011-06-10 15:37:27 -07001256
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001257 default:
1258 break;
Stephen Hines48b72bf2011-06-10 15:37:27 -07001259 }
1260
1261 if (!TypeName.empty()) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001262 mOut.indent() << "if (!" << VarName
1263 << ".getType().getElement().isCompatible(" RS_ELEM_PREFIX
1264 << TypeName << ")) {\n";
1265 mOut.indent() << " throw new RSRuntimeException(\"Type mismatch with "
1266 << TypeName << "!\");\n";
1267 mOut.indent() << "}\n";
Stephen Hines48b72bf2011-06-10 15:37:27 -07001268 }
Stephen Hinesb5a89fb2011-05-17 14:48:02 -07001269}
1270
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001271void RSReflectionJava::genPrimitiveTypeExportVariable(const RSExportVar *EV) {
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001272 slangAssert(
1273 (EV->getType()->getClass() == RSExportType::ExportClassPrimitive) &&
1274 "Variable should be type of primitive here");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001275
1276 const RSExportPrimitiveType *EPT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001277 static_cast<const RSExportPrimitiveType *>(EV->getType());
Stephen Hines0d26cef2012-05-01 19:23:01 -07001278 std::string TypeName = GetTypeName(EPT);
1279 std::string VarName = EV->getName();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001280
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001281 genPrivateExportVariable(TypeName, EV->getName());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001282
Stephen Hines5d671782012-01-31 19:32:04 -08001283 if (EV->isConst()) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001284 mOut.indent() << "public final static " << TypeName
1285 << " " RS_EXPORT_VAR_CONST_PREFIX << VarName << " = ";
Stephen Hines5d671782012-01-31 19:32:04 -08001286 const clang::APValue &Val = EV->getInit();
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001287 genInitValue(Val, EPT->getType() == DataTypeBoolean);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001288 mOut << ";\n";
Stephen Hines5d671782012-01-31 19:32:04 -08001289 } else {
1290 // set_*()
Stephen Hines1f6c3312012-07-03 17:23:33 -07001291 // This must remain synchronized, since multiple Dalvik threads may
1292 // be calling setters.
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001293 startFunction(AM_PublicSynchronized, false, "void", "set_" + VarName, 1,
1294 TypeName.c_str(), "v");
Stephen Hinesbcae1fe2012-09-25 19:17:33 -07001295 if ((EPT->getSize() < 4) || EV->isUnsigned()) {
Stephen Hines1f6c3312012-07-03 17:23:33 -07001296 // We create/cache a per-type FieldPacker. This allows us to reuse the
1297 // validation logic (for catching negative inputs from Dalvik, as well
1298 // as inputs that are too large to be represented in the unsigned type).
Stephen Hinesbcae1fe2012-09-25 19:17:33 -07001299 // Sub-integer types are also handled specially here, so that we don't
1300 // overwrite bytes accidentally.
Stephen Hines1f6c3312012-07-03 17:23:33 -07001301 std::string ElemName = EPT->getElementName();
1302 std::string FPName;
1303 FPName = RS_FP_PREFIX + ElemName;
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001304 mOut.indent() << "if (" << FPName << "!= null) {\n";
1305 mOut.increaseIndent();
1306 mOut.indent() << FPName << ".reset();\n";
1307 mOut.decreaseIndent();
1308 mOut.indent() << "} else {\n";
1309 mOut.increaseIndent();
1310 mOut.indent() << FPName << " = new FieldPacker(" << EPT->getSize()
1311 << ");\n";
1312 mOut.decreaseIndent();
1313 mOut.indent() << "}\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001314
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001315 genPackVarOfType(EPT, "v", FPName.c_str());
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001316 mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
1317 << ", " << FPName << ");\n";
Stephen Hines1f6c3312012-07-03 17:23:33 -07001318 } else {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001319 mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
1320 << ", v);\n";
Stephen Hines1f6c3312012-07-03 17:23:33 -07001321 }
1322
1323 // Dalvik update comes last, since the input may be invalid (and hence
1324 // throw an exception).
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001325 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001326
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001327 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001328 }
Shih-wei Liao9e86e192010-06-18 20:42:28 -07001329
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001330 genGetExportVariable(TypeName, VarName);
1331 genGetFieldID(VarName);
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001332}
1333
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001334void RSReflectionJava::genInitValue(const clang::APValue &Val, bool asBool) {
1335 switch (Val.getKind()) {
1336 case clang::APValue::Int: {
1337 llvm::APInt api = Val.getInt();
1338 if (asBool) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001339 mOut << ((api.getSExtValue() == 0) ? "false" : "true");
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001340 } else {
1341 // TODO: Handle unsigned correctly
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001342 mOut << api.getSExtValue();
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001343 if (api.getBitWidth() > 32) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001344 mOut << "L";
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001345 }
1346 }
1347 break;
1348 }
1349
1350 case clang::APValue::Float: {
1351 llvm::APFloat apf = Val.getFloat();
1352 llvm::SmallString<30> s;
1353 apf.toString(s);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001354 mOut << s.c_str();
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001355 if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) {
1356 if (s.count('.') == 0) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001357 mOut << ".f";
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001358 } else {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001359 mOut << "f";
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001360 }
1361 }
1362 break;
1363 }
1364
1365 case clang::APValue::ComplexInt:
1366 case clang::APValue::ComplexFloat:
1367 case clang::APValue::LValue:
1368 case clang::APValue::Vector: {
1369 slangAssert(false && "Primitive type cannot have such kind of initializer");
1370 break;
1371 }
1372
1373 default: { slangAssert(false && "Unknown kind of initializer"); }
1374 }
1375}
1376
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001377void RSReflectionJava::genPointerTypeExportVariable(const RSExportVar *EV) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001378 const RSExportType *ET = EV->getType();
1379 const RSExportType *PointeeType;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001380
Stephen Hines6e6578a2011-02-07 18:05:48 -08001381 slangAssert((ET->getClass() == RSExportType::ExportClassPointer) &&
1382 "Variable should be type of pointer here");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001383
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001384 PointeeType = static_cast<const RSExportPointerType *>(ET)->getPointeeType();
Stephen Hines0d26cef2012-05-01 19:23:01 -07001385 std::string TypeName = GetTypeName(ET);
1386 std::string VarName = EV->getName();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001387
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001388 genPrivateExportVariable(TypeName, VarName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001389
Zonr Chang89273bd2010-10-14 20:57:38 +08001390 // bind_*()
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001391 startFunction(AM_Public, false, "void", "bind_" + VarName, 1,
1392 TypeName.c_str(), "v");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001393
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001394 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
1395 mOut.indent() << "if (v == null) bindAllocation(null, "
1396 << RS_EXPORT_VAR_INDEX_PREFIX << VarName << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001397
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001398 if (PointeeType->getClass() == RSExportType::ExportClassRecord) {
1399 mOut.indent() << "else bindAllocation(v.getAllocation(), "
1400 << RS_EXPORT_VAR_INDEX_PREFIX << VarName << ");\n";
1401 } else {
1402 mOut.indent() << "else bindAllocation(v, " << RS_EXPORT_VAR_INDEX_PREFIX
1403 << VarName << ");\n";
1404 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001405
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001406 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001407
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001408 genGetExportVariable(TypeName, VarName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001409}
1410
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001411void RSReflectionJava::genVectorTypeExportVariable(const RSExportVar *EV) {
Stephen Hines6e6578a2011-02-07 18:05:48 -08001412 slangAssert((EV->getType()->getClass() == RSExportType::ExportClassVector) &&
1413 "Variable should be type of vector here");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001414
Stephen Hines0d26cef2012-05-01 19:23:01 -07001415 std::string TypeName = GetTypeName(EV->getType());
1416 std::string VarName = EV->getName();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001417
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001418 genPrivateExportVariable(TypeName, VarName);
1419 genSetExportVariable(TypeName, EV);
1420 genGetExportVariable(TypeName, VarName);
1421 genGetFieldID(VarName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001422}
1423
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001424void RSReflectionJava::genMatrixTypeExportVariable(const RSExportVar *EV) {
Stephen Hines6e6578a2011-02-07 18:05:48 -08001425 slangAssert((EV->getType()->getClass() == RSExportType::ExportClassMatrix) &&
1426 "Variable should be type of matrix here");
Zonr Chang92b344a2010-10-05 20:39:03 +08001427
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001428 const RSExportType *ET = EV->getType();
Stephen Hines0d26cef2012-05-01 19:23:01 -07001429 std::string TypeName = GetTypeName(ET);
1430 std::string VarName = EV->getName();
Zonr Chang92b344a2010-10-05 20:39:03 +08001431
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001432 genPrivateExportVariable(TypeName, VarName);
Zonr Chang92b344a2010-10-05 20:39:03 +08001433
1434 // set_*()
1435 if (!EV->isConst()) {
Stephen Hines0d26cef2012-05-01 19:23:01 -07001436 const char *FieldPackerName = "fp";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001437 startFunction(AM_PublicSynchronized, false, "void", "set_" + VarName, 1,
1438 TypeName.c_str(), "v");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001439 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
Zonr Chang92b344a2010-10-05 20:39:03 +08001440
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001441 if (genCreateFieldPacker(ET, FieldPackerName))
1442 genPackVarOfType(ET, "v", FieldPackerName);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001443 mOut.indent() << "setVar(" RS_EXPORT_VAR_INDEX_PREFIX << VarName << ", "
1444 << FieldPackerName << ");\n";
Zonr Chang92b344a2010-10-05 20:39:03 +08001445
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001446 endFunction();
Zonr Chang92b344a2010-10-05 20:39:03 +08001447 }
1448
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001449 genGetExportVariable(TypeName, VarName);
1450 genGetFieldID(VarName);
Zonr Chang92b344a2010-10-05 20:39:03 +08001451}
1452
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001453void
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001454RSReflectionJava::genConstantArrayTypeExportVariable(const RSExportVar *EV) {
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001455 slangAssert(
1456 (EV->getType()->getClass() == RSExportType::ExportClassConstantArray) &&
1457 "Variable should be type of constant array here");
Zonr Chang2e1dba62010-10-05 22:20:11 +08001458
Stephen Hines0d26cef2012-05-01 19:23:01 -07001459 std::string TypeName = GetTypeName(EV->getType());
1460 std::string VarName = EV->getName();
Zonr Chang2e1dba62010-10-05 22:20:11 +08001461
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001462 genPrivateExportVariable(TypeName, VarName);
1463 genSetExportVariable(TypeName, EV);
1464 genGetExportVariable(TypeName, VarName);
1465 genGetFieldID(VarName);
Zonr Chang2e1dba62010-10-05 22:20:11 +08001466}
1467
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001468void RSReflectionJava::genRecordTypeExportVariable(const RSExportVar *EV) {
Stephen Hines6e6578a2011-02-07 18:05:48 -08001469 slangAssert((EV->getType()->getClass() == RSExportType::ExportClassRecord) &&
1470 "Variable should be type of struct here");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001471
Stephen Hines0d26cef2012-05-01 19:23:01 -07001472 std::string TypeName = GetTypeName(EV->getType());
1473 std::string VarName = EV->getName();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001474
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001475 genPrivateExportVariable(TypeName, VarName);
1476 genSetExportVariable(TypeName, EV);
1477 genGetExportVariable(TypeName, VarName);
1478 genGetFieldID(VarName);
Stephen Hines0d26cef2012-05-01 19:23:01 -07001479}
1480
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001481void RSReflectionJava::genPrivateExportVariable(const std::string &TypeName,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001482 const std::string &VarName) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001483 mOut.indent() << "private " << TypeName << " " << RS_EXPORT_VAR_PREFIX
1484 << VarName << ";\n";
Stephen Hines0d26cef2012-05-01 19:23:01 -07001485}
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001486
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001487void RSReflectionJava::genSetExportVariable(const std::string &TypeName,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001488 const RSExportVar *EV) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001489 if (!EV->isConst()) {
Stephen Hines0d26cef2012-05-01 19:23:01 -07001490 const char *FieldPackerName = "fp";
1491 std::string VarName = EV->getName();
1492 const RSExportType *ET = EV->getType();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001493 startFunction(AM_PublicSynchronized, false, "void", "set_" + VarName, 1,
1494 TypeName.c_str(), "v");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001495 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001496
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001497 if (genCreateFieldPacker(ET, FieldPackerName))
1498 genPackVarOfType(ET, "v", FieldPackerName);
Stephen Hinesa6b54142012-04-09 18:25:08 -07001499
1500 if (mRSContext->getTargetAPI() < SLANG_JB_TARGET_API) {
1501 // Legacy apps must use the old setVar() without Element/dim components.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001502 mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
1503 << ", " << FieldPackerName << ");\n";
Stephen Hinesa6b54142012-04-09 18:25:08 -07001504 } else {
1505 // We only have support for one-dimensional array reflection today,
1506 // but the entry point (i.e. setVar()) takes an array of dimensions.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001507 mOut.indent() << "int []__dimArr = new int[1];\n";
1508 mOut.indent() << "__dimArr[0] = " << ET->getSize() << ";\n";
1509 mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
1510 << ", " << FieldPackerName << ", " << RS_ELEM_PREFIX
1511 << ET->getElementName() << ", __dimArr);\n";
Stephen Hinesa6b54142012-04-09 18:25:08 -07001512 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001513
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001514 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001515 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001516}
1517
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001518void RSReflectionJava::genGetExportVariable(const std::string &TypeName,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001519 const std::string &VarName) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001520 startFunction(AM_Public, false, TypeName.c_str(), "get_" + VarName, 0);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001521
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001522 mOut.indent() << "return " << RS_EXPORT_VAR_PREFIX << VarName << ";\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001523
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001524 endFunction();
Stephen Hines28d60bc2012-10-15 15:54:16 -07001525}
1526
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001527void RSReflectionJava::genGetFieldID(const std::string &VarName) {
Stephen Hines28d60bc2012-10-15 15:54:16 -07001528 // We only generate getFieldID_*() for non-Pointer (bind) types.
Tim Murrayb81a9932012-10-10 15:56:02 -07001529 if (mRSContext->getTargetAPI() >= SLANG_JB_MR1_TARGET_API) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001530 startFunction(AM_Public, false, "Script.FieldID", "getFieldID_" + VarName,
1531 0);
Tim Murrayb81a9932012-10-10 15:56:02 -07001532
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001533 mOut.indent() << "return createFieldID(" << RS_EXPORT_VAR_INDEX_PREFIX
1534 << VarName << ", null);\n";
Tim Murrayb81a9932012-10-10 15:56:02 -07001535
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001536 endFunction();
Tim Murrayb81a9932012-10-10 15:56:02 -07001537 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001538}
1539
1540/******************* Methods to generate script class /end *******************/
1541
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001542bool RSReflectionJava::genCreateFieldPacker(const RSExportType *ET,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001543 const char *FieldPackerName) {
Jean-Luc Brouilletc95381a2014-05-14 21:24:45 -07001544 size_t AllocSize = ET->getAllocSize();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001545 if (AllocSize > 0)
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001546 mOut.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker("
1547 << AllocSize << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001548 else
1549 return false;
1550 return true;
1551}
1552
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001553void RSReflectionJava::genPackVarOfType(const RSExportType *ET,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001554 const char *VarName,
1555 const char *FieldPackerName) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001556 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001557 case RSExportType::ExportClassPrimitive:
1558 case RSExportType::ExportClassVector: {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001559 mOut.indent() << FieldPackerName << "."
1560 << GetPackerAPIName(
1561 static_cast<const RSExportPrimitiveType *>(ET)) << "("
1562 << VarName << ");\n";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001563 break;
1564 }
1565 case RSExportType::ExportClassPointer: {
1566 // Must reflect as type Allocation in Java
1567 const RSExportType *PointeeType =
1568 static_cast<const RSExportPointerType *>(ET)->getPointeeType();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001569
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001570 if (PointeeType->getClass() != RSExportType::ExportClassRecord) {
1571 mOut.indent() << FieldPackerName << ".addI32(" << VarName
1572 << ".getPtr());\n";
1573 } else {
1574 mOut.indent() << FieldPackerName << ".addI32(" << VarName
1575 << ".getAllocation().getPtr());\n";
1576 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001577 break;
1578 }
1579 case RSExportType::ExportClassMatrix: {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001580 mOut.indent() << FieldPackerName << ".addMatrix(" << VarName << ");\n";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001581 break;
1582 }
1583 case RSExportType::ExportClassConstantArray: {
1584 const RSExportConstantArrayType *ECAT =
1585 static_cast<const RSExportConstantArrayType *>(ET);
1586
1587 // TODO(zonr): more elegant way. Currently, we obtain the unique index
1588 // variable (this method involves recursive call which means
1589 // we may have more than one level loop, therefore we can't
1590 // always use the same index variable name here) name given
1591 // in the for-loop from counting the '.' in @VarName.
1592 unsigned Level = 0;
1593 size_t LastDotPos = 0;
1594 std::string ElementVarName(VarName);
1595
1596 while (LastDotPos != std::string::npos) {
1597 LastDotPos = ElementVarName.find_first_of('.', LastDotPos + 1);
1598 Level++;
1599 }
1600 std::string IndexVarName("ct");
1601 IndexVarName.append(llvm::utostr_32(Level));
1602
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001603 mOut.indent() << "for (int " << IndexVarName << " = 0; " << IndexVarName
1604 << " < " << ECAT->getSize() << "; " << IndexVarName << "++)";
1605 mOut.startBlock();
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001606
1607 ElementVarName.append("[" + IndexVarName + "]");
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001608 genPackVarOfType(ECAT->getElementType(), ElementVarName.c_str(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001609 FieldPackerName);
1610
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001611 mOut.endBlock();
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001612 break;
1613 }
1614 case RSExportType::ExportClassRecord: {
1615 const RSExportRecordType *ERT = static_cast<const RSExportRecordType *>(ET);
1616 // Relative pos from now on in field packer
1617 unsigned Pos = 0;
1618
1619 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
1620 E = ERT->fields_end();
1621 I != E; I++) {
1622 const RSExportRecordType::Field *F = *I;
1623 std::string FieldName;
1624 size_t FieldOffset = F->getOffsetInParent();
1625 const RSExportType *T = F->getType();
1626 size_t FieldStoreSize = T->getStoreSize();
1627 size_t FieldAllocSize = T->getAllocSize();
1628
Chris Wailes5abbe0e2014-08-12 15:58:29 -07001629 if (VarName != nullptr)
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001630 FieldName = VarName + ("." + F->getName());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001631 else
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001632 FieldName = F->getName();
Zonr Chang89273bd2010-10-14 20:57:38 +08001633
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001634 if (FieldOffset > Pos) {
1635 mOut.indent() << FieldPackerName << ".skip(" << (FieldOffset - Pos)
1636 << ");\n";
1637 }
Zonr Chang89273bd2010-10-14 20:57:38 +08001638
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001639 genPackVarOfType(F->getType(), FieldName.c_str(), FieldPackerName);
Zonr Chang89273bd2010-10-14 20:57:38 +08001640
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001641 // There is padding in the field type
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001642 if (FieldAllocSize > FieldStoreSize) {
1643 mOut.indent() << FieldPackerName << ".skip("
1644 << (FieldAllocSize - FieldStoreSize) << ");\n";
1645 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001646
1647 Pos = FieldOffset + FieldAllocSize;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001648 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001649
1650 // There maybe some padding after the struct
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001651 if (ERT->getAllocSize() > Pos) {
1652 mOut.indent() << FieldPackerName << ".skip(" << ERT->getAllocSize() - Pos
1653 << ");\n";
1654 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001655 break;
1656 }
1657 default: { slangAssert(false && "Unknown class of type"); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001658 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001659}
1660
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001661void RSReflectionJava::genAllocateVarOfType(const RSExportType *T,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001662 const std::string &VarName) {
Zonr Chang2e1dba62010-10-05 22:20:11 +08001663 switch (T->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001664 case RSExportType::ExportClassPrimitive: {
1665 // Primitive type like int in Java has its own storage once it's declared.
1666 //
1667 // FIXME: Should we allocate storage for RS object?
1668 // if (static_cast<const RSExportPrimitiveType *>(T)->isRSObjectType())
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001669 // mOut.indent() << VarName << " = new " << GetTypeName(T) << "();\n";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001670 break;
1671 }
1672 case RSExportType::ExportClassPointer: {
1673 // Pointer type is an instance of Allocation or a TypeClass whose value is
1674 // expected to be assigned by programmer later in Java program. Therefore
1675 // we don't reflect things like [VarName] = new Allocation();
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001676 mOut.indent() << VarName << " = null;\n";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001677 break;
1678 }
1679 case RSExportType::ExportClassConstantArray: {
1680 const RSExportConstantArrayType *ECAT =
1681 static_cast<const RSExportConstantArrayType *>(T);
1682 const RSExportType *ElementType = ECAT->getElementType();
Zonr Chang2e1dba62010-10-05 22:20:11 +08001683
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001684 mOut.indent() << VarName << " = new " << GetTypeName(ElementType) << "["
1685 << ECAT->getSize() << "];\n";
Zonr Chang2f1451c2010-10-14 02:58:28 +08001686
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001687 // Primitive type element doesn't need allocation code.
1688 if (ElementType->getClass() != RSExportType::ExportClassPrimitive) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001689 mOut.indent() << "for (int $ct = 0; $ct < " << ECAT->getSize()
1690 << "; $ct++)";
1691 mOut.startBlock();
Zonr Chang2e1dba62010-10-05 22:20:11 +08001692
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001693 std::string ElementVarName(VarName);
1694 ElementVarName.append("[$ct]");
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001695 genAllocateVarOfType(ElementType, ElementVarName);
Zonr Chang2e1dba62010-10-05 22:20:11 +08001696
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001697 mOut.endBlock();
Zonr Chang2e1dba62010-10-05 22:20:11 +08001698 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001699 break;
1700 }
1701 case RSExportType::ExportClassVector:
1702 case RSExportType::ExportClassMatrix:
1703 case RSExportType::ExportClassRecord: {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001704 mOut.indent() << VarName << " = new " << GetTypeName(T) << "();\n";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001705 break;
1706 }
Zonr Chang2e1dba62010-10-05 22:20:11 +08001707 }
Zonr Chang2e1dba62010-10-05 22:20:11 +08001708}
1709
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001710void RSReflectionJava::genNewItemBufferIfNull(const char *Index) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001711 mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME " == null) ";
1712 mOut << RS_TYPE_ITEM_BUFFER_NAME << " = new " << RS_TYPE_ITEM_CLASS_NAME
1713 << "[getType().getX() /* count */];\n";
Chris Wailes5abbe0e2014-08-12 15:58:29 -07001714 if (Index != nullptr) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001715 mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME << "[" << Index
1716 << "] == null) ";
1717 mOut << RS_TYPE_ITEM_BUFFER_NAME << "[" << Index << "] = new "
1718 << RS_TYPE_ITEM_CLASS_NAME << "();\n";
1719 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001720}
1721
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001722void RSReflectionJava::genNewItemBufferPackerIfNull() {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001723 mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " == null) ";
1724 mOut << RS_TYPE_ITEM_BUFFER_PACKER_NAME " = new FieldPacker("
Tim Murray3a38b742014-07-02 10:41:08 -07001725 << mItemSizeof << " * getType().getX()/* count */);\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001726}
1727
1728/********************** Methods to generate type class **********************/
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001729bool RSReflectionJava::genTypeClass(const RSExportRecordType *ERT,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001730 std::string &ErrorMsg) {
Stephen Hinesa6b54142012-04-09 18:25:08 -07001731 std::string ClassName = ERT->getElementName();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001732 std::string superClassName = getRSPackageName();
Tim Murrayf69e1e52013-01-17 13:57:24 -08001733 superClassName += RS_TYPE_CLASS_SUPER_CLASS_NAME;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001734
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001735 if (!startClass(AM_Public, false, ClassName, superClassName.c_str(),
1736 ErrorMsg))
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001737 return false;
1738
Stephen Hines4cc67fc2011-01-31 16:48:57 -08001739 mGeneratedFileNames->push_back(ClassName);
1740
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001741 genTypeItemClass(ERT);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001742
1743 // Declare item buffer and item buffer packer
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001744 mOut.indent() << "private " << RS_TYPE_ITEM_CLASS_NAME << " "
1745 << RS_TYPE_ITEM_BUFFER_NAME << "[];\n";
1746 mOut.indent() << "private FieldPacker " << RS_TYPE_ITEM_BUFFER_PACKER_NAME
1747 << ";\n";
1748 mOut.indent() << "private static java.lang.ref.WeakReference<Element> "
1749 << RS_TYPE_ELEMENT_REF_NAME
1750 << " = new java.lang.ref.WeakReference<Element>(null);\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001751
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001752 genTypeClassConstructor(ERT);
1753 genTypeClassCopyToArrayLocal(ERT);
1754 genTypeClassCopyToArray(ERT);
1755 genTypeClassItemSetter(ERT);
1756 genTypeClassItemGetter(ERT);
1757 genTypeClassComponentSetter(ERT);
1758 genTypeClassComponentGetter(ERT);
1759 genTypeClassCopyAll(ERT);
Stephen Hines82754d82013-01-18 19:46:06 -08001760 if (!mRSContext->isCompatLib()) {
1761 // Skip the resize method if we are targeting a compatibility library.
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001762 genTypeClassResize();
Stephen Hines82754d82013-01-18 19:46:06 -08001763 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001764
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001765 endClass();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001766
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001767 resetFieldIndex();
1768 clearFieldIndexMap();
Zonr Chang66aa2992010-10-05 15:56:31 +08001769
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001770 return true;
1771}
1772
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001773void RSReflectionJava::genTypeItemClass(const RSExportRecordType *ERT) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001774 mOut.indent() << "static public class " RS_TYPE_ITEM_CLASS_NAME;
1775 mOut.startBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001776
Tim Murray3a38b742014-07-02 10:41:08 -07001777 // Sizeof should not be exposed for 64-bit; it is not accurate
1778 if (mRSContext->getTargetAPI() < 21) {
1779 mOut.indent() << "public static final int sizeof = " << ERT->getAllocSize()
1780 << ";\n";
1781 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001782
1783 // Member elements
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001784 mOut << "\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001785 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001786 FE = ERT->fields_end();
1787 FI != FE; FI++) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001788 mOut.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName()
1789 << ";\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001790 }
1791
1792 // Constructor
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001793 mOut << "\n";
1794 mOut.indent() << RS_TYPE_ITEM_CLASS_NAME << "()";
1795 mOut.startBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001796
1797 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001798 FE = ERT->fields_end();
1799 FI != FE; FI++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001800 const RSExportRecordType::Field *F = *FI;
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001801 genAllocateVarOfType(F->getType(), F->getName());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001802 }
1803
1804 // end Constructor
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001805 mOut.endBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001806
1807 // end Item class
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001808 mOut.endBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001809}
1810
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001811void RSReflectionJava::genTypeClassConstructor(const RSExportRecordType *ERT) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001812 const char *RenderScriptVar = "rs";
1813
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001814 startFunction(AM_Public, true, "Element", "createElement", 1, "RenderScript",
1815 RenderScriptVar);
Jason Sams381e95f2011-11-30 14:01:43 -08001816
Stephen Hinese67239d2012-02-24 15:08:36 -08001817 // TODO(all): Fix weak-refs + multi-context issue.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001818 // mOut.indent() << "Element e = " << RS_TYPE_ELEMENT_REF_NAME
Jean-Luc Brouillet29689212014-05-27 13:25:31 -07001819 // << ".get();\n";
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001820 // mOut.indent() << "if (e != null) return e;\n";
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001821 RSReflectionJavaElementBuilder builder("eb", ERT, RenderScriptVar, &mOut,
1822 mRSContext, this);
1823 builder.generate();
1824
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001825 mOut.indent() << "return eb.create();\n";
1826 // mOut.indent() << "e = eb.create();\n";
1827 // mOut.indent() << RS_TYPE_ELEMENT_REF_NAME
Jean-Luc Brouillet29689212014-05-27 13:25:31 -07001828 // << " = new java.lang.ref.WeakReference<Element>(e);\n";
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001829 // mOut.indent() << "return e;\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001830 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001831
Jason Sams381e95f2011-11-30 14:01:43 -08001832 // private with element
Chris Wailes5abbe0e2014-08-12 15:58:29 -07001833 startFunction(AM_Private, false, nullptr, getClassName(), 1, "RenderScript",
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001834 RenderScriptVar);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001835 mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
1836 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
1837 mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001838 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001839
1840 // 1D without usage
Chris Wailes5abbe0e2014-08-12 15:58:29 -07001841 startFunction(AM_Public, false, nullptr, getClassName(), 2, "RenderScript",
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001842 RenderScriptVar, "int", "count");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001843
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001844 mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
1845 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
1846 mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001847 // Call init() in super class
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001848 mOut.indent() << "init(" << RenderScriptVar << ", count);\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001849 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001850
Jason Sams381e95f2011-11-30 14:01:43 -08001851 // 1D with usage
Chris Wailes5abbe0e2014-08-12 15:58:29 -07001852 startFunction(AM_Public, false, nullptr, getClassName(), 3, "RenderScript",
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001853 RenderScriptVar, "int", "count", "int", "usages");
Jason Sams91fe83b2010-12-06 17:07:12 -08001854
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001855 mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
1856 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
1857 mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
Jason Sams91fe83b2010-12-06 17:07:12 -08001858 // Call init() in super class
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001859 mOut.indent() << "init(" << RenderScriptVar << ", count, usages);\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001860 endFunction();
Jason Sams91fe83b2010-12-06 17:07:12 -08001861
Jason Sams381e95f2011-11-30 14:01:43 -08001862 // create1D with usage
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001863 startFunction(AM_Public, true, getClassName().c_str(), "create1D", 3,
1864 "RenderScript", RenderScriptVar, "int", "dimX", "int",
1865 "usages");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001866 mOut.indent() << getClassName() << " obj = new " << getClassName() << "("
1867 << RenderScriptVar << ");\n";
1868 mOut.indent() << "obj.mAllocation = Allocation.createSized("
1869 "rs, obj.mElement, dimX, usages);\n";
1870 mOut.indent() << "return obj;\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001871 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001872
1873 // create1D without usage
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001874 startFunction(AM_Public, true, getClassName().c_str(), "create1D", 2,
1875 "RenderScript", RenderScriptVar, "int", "dimX");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001876 mOut.indent() << "return create1D(" << RenderScriptVar
1877 << ", dimX, Allocation.USAGE_SCRIPT);\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001878 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001879
Jason Sams381e95f2011-11-30 14:01:43 -08001880 // create2D without usage
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001881 startFunction(AM_Public, true, getClassName().c_str(), "create2D", 3,
1882 "RenderScript", RenderScriptVar, "int", "dimX", "int", "dimY");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001883 mOut.indent() << "return create2D(" << RenderScriptVar
1884 << ", dimX, dimY, Allocation.USAGE_SCRIPT);\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001885 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001886
1887 // create2D with usage
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001888 startFunction(AM_Public, true, getClassName().c_str(), "create2D", 4,
1889 "RenderScript", RenderScriptVar, "int", "dimX", "int", "dimY",
1890 "int", "usages");
Jason Sams381e95f2011-11-30 14:01:43 -08001891
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001892 mOut.indent() << getClassName() << " obj = new " << getClassName() << "("
1893 << RenderScriptVar << ");\n";
1894 mOut.indent() << "Type.Builder b = new Type.Builder(rs, obj.mElement);\n";
1895 mOut.indent() << "b.setX(dimX);\n";
1896 mOut.indent() << "b.setY(dimY);\n";
1897 mOut.indent() << "Type t = b.create();\n";
1898 mOut.indent() << "obj.mAllocation = Allocation.createTyped(rs, t, usages);\n";
1899 mOut.indent() << "return obj;\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001900 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001901
Jason Sams381e95f2011-11-30 14:01:43 -08001902 // createTypeBuilder
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001903 startFunction(AM_Public, true, "Type.Builder", "createTypeBuilder", 1,
1904 "RenderScript", RenderScriptVar);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001905 mOut.indent() << "Element e = createElement(" << RenderScriptVar << ");\n";
1906 mOut.indent() << "return new Type.Builder(rs, e);\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001907 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001908
1909 // createCustom with usage
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001910 startFunction(AM_Public, true, getClassName().c_str(), "createCustom", 3,
1911 "RenderScript", RenderScriptVar, "Type.Builder", "tb", "int",
1912 "usages");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001913 mOut.indent() << getClassName() << " obj = new " << getClassName() << "("
1914 << RenderScriptVar << ");\n";
1915 mOut.indent() << "Type t = tb.create();\n";
1916 mOut.indent() << "if (t.getElement() != obj.mElement) {\n";
1917 mOut.indent() << " throw new RSIllegalArgumentException("
1918 "\"Type.Builder did not match expected element type.\");\n";
1919 mOut.indent() << "}\n";
1920 mOut.indent() << "obj.mAllocation = Allocation.createTyped(rs, t, usages);\n";
1921 mOut.indent() << "return obj;\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001922 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001923}
1924
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001925void RSReflectionJava::genTypeClassCopyToArray(const RSExportRecordType *ERT) {
1926 startFunction(AM_Private, false, "void", "copyToArray", 2,
1927 RS_TYPE_ITEM_CLASS_NAME, "i", "int", "index");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001928
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001929 genNewItemBufferPackerIfNull();
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001930 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << ".reset(index * "
Tim Murray3a38b742014-07-02 10:41:08 -07001931 << mItemSizeof << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001932
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001933 mOut.indent() << "copyToArrayLocal(i, " RS_TYPE_ITEM_BUFFER_PACKER_NAME
1934 ");\n";
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001935
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001936 endFunction();
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001937}
1938
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001939void
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001940RSReflectionJava::genTypeClassCopyToArrayLocal(const RSExportRecordType *ERT) {
1941 startFunction(AM_Private, false, "void", "copyToArrayLocal", 2,
1942 RS_TYPE_ITEM_CLASS_NAME, "i", "FieldPacker", "fp");
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001943
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001944 genPackVarOfType(ERT, "i", "fp");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001945
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001946 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001947}
1948
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001949void RSReflectionJava::genTypeClassItemSetter(const RSExportRecordType *ERT) {
1950 startFunction(AM_PublicSynchronized, false, "void", "set", 3,
1951 RS_TYPE_ITEM_CLASS_NAME, "i", "int", "index", "boolean",
1952 "copyNow");
Chris Wailes5abbe0e2014-08-12 15:58:29 -07001953 genNewItemBufferIfNull(nullptr);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001954 mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << "[index] = i;\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001955
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001956 mOut.indent() << "if (copyNow) ";
1957 mOut.startBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001958
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001959 mOut.indent() << "copyToArray(i, index);\n";
Tim Murray3a38b742014-07-02 10:41:08 -07001960 mOut.indent() << "FieldPacker fp = new FieldPacker(" << mItemSizeof << ");\n";
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001961 mOut.indent() << "copyToArrayLocal(i, fp);\n";
1962 mOut.indent() << "mAllocation.setFromFieldPacker(index, fp);\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001963
1964 // End of if (copyNow)
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001965 mOut.endBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001966
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001967 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001968}
1969
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001970void RSReflectionJava::genTypeClassItemGetter(const RSExportRecordType *ERT) {
1971 startFunction(AM_PublicSynchronized, false, RS_TYPE_ITEM_CLASS_NAME, "get", 1,
1972 "int", "index");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001973 mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME
1974 << " == null) return null;\n";
1975 mOut.indent() << "return " << RS_TYPE_ITEM_BUFFER_NAME << "[index];\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001976 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001977}
1978
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001979void
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001980RSReflectionJava::genTypeClassComponentSetter(const RSExportRecordType *ERT) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001981 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001982 FE = ERT->fields_end();
1983 FI != FE; FI++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001984 const RSExportRecordType::Field *F = *FI;
1985 size_t FieldOffset = F->getOffsetInParent();
Jean-Luc Brouilletc95381a2014-05-14 21:24:45 -07001986 size_t FieldStoreSize = F->getType()->getStoreSize();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001987 unsigned FieldIndex = getFieldIndex(F);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001988
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001989 startFunction(AM_PublicSynchronized, false, "void", "set_" + F->getName(),
1990 3, "int", "index", GetTypeName(F->getType()).c_str(), "v",
1991 "boolean", "copyNow");
1992 genNewItemBufferPackerIfNull();
1993 genNewItemBufferIfNull("index");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001994 mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << "[index]." << F->getName()
1995 << " = v;\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001996
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001997 mOut.indent() << "if (copyNow) ";
1998 mOut.startBlock();
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -07001999
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002000 if (FieldOffset > 0) {
2001 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << ".reset(index * "
Tim Murray3a38b742014-07-02 10:41:08 -07002002 << mItemSizeof << " + " << FieldOffset
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002003 << ");\n";
2004 } else {
2005 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << ".reset(index * "
Tim Murray3a38b742014-07-02 10:41:08 -07002006 << mItemSizeof << ");\n";
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002007 }
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002008 genPackVarOfType(F->getType(), "v", RS_TYPE_ITEM_BUFFER_PACKER_NAME);
2009
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002010 mOut.indent() << "FieldPacker fp = new FieldPacker(" << FieldStoreSize
2011 << ");\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002012 genPackVarOfType(F->getType(), "v", "fp");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002013 mOut.indent() << "mAllocation.setFromFieldPacker(index, " << FieldIndex
2014 << ", fp);\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002015
2016 // End of if (copyNow)
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002017 mOut.endBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002018
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002019 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002020 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002021}
2022
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07002023void
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002024RSReflectionJava::genTypeClassComponentGetter(const RSExportRecordType *ERT) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002025 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07002026 FE = ERT->fields_end();
2027 FI != FE; FI++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002028 const RSExportRecordType::Field *F = *FI;
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002029 startFunction(AM_PublicSynchronized, false,
2030 GetTypeName(F->getType()).c_str(), "get_" + F->getName(), 1,
2031 "int", "index");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002032 mOut.indent() << "if (" RS_TYPE_ITEM_BUFFER_NAME << " == null) return "
2033 << GetTypeNullValue(F->getType()) << ";\n";
2034 mOut.indent() << "return " RS_TYPE_ITEM_BUFFER_NAME << "[index]."
2035 << F->getName() << ";\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002036 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002037 }
Shih-wei Liao9c631ff2010-09-17 11:57:29 -07002038}
2039
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002040void RSReflectionJava::genTypeClassCopyAll(const RSExportRecordType *ERT) {
2041 startFunction(AM_PublicSynchronized, false, "void", "copyAll", 0);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002042
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002043 mOut.indent() << "for (int ct = 0; ct < " << RS_TYPE_ITEM_BUFFER_NAME
2044 << ".length; ct++)"
2045 << " copyToArray(" << RS_TYPE_ITEM_BUFFER_NAME
2046 << "[ct], ct);\n";
2047 mOut.indent() << "mAllocation.setFromFieldPacker(0, "
2048 << RS_TYPE_ITEM_BUFFER_PACKER_NAME ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002049
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002050 endFunction();
Shih-wei Liao9c631ff2010-09-17 11:57:29 -07002051}
2052
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002053void RSReflectionJava::genTypeClassResize() {
2054 startFunction(AM_PublicSynchronized, false, "void", "resize", 1, "int",
2055 "newSize");
Zonr Changd42a4292010-10-17 02:38:43 +08002056
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002057 mOut.indent() << "if (mItemArray != null) ";
2058 mOut.startBlock();
2059 mOut.indent() << "int oldSize = mItemArray.length;\n";
2060 mOut.indent() << "int copySize = Math.min(oldSize, newSize);\n";
2061 mOut.indent() << "if (newSize == oldSize) return;\n";
2062 mOut.indent() << "Item ni[] = new Item[newSize];\n";
2063 mOut.indent() << "System.arraycopy(mItemArray, 0, ni, 0, copySize);\n";
2064 mOut.indent() << "mItemArray = ni;\n";
2065 mOut.endBlock();
2066 mOut.indent() << "mAllocation.resize(newSize);\n";
Zonr Changd42a4292010-10-17 02:38:43 +08002067
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002068 mOut.indent() << "if (" RS_TYPE_ITEM_BUFFER_PACKER_NAME
2069 " != null) " RS_TYPE_ITEM_BUFFER_PACKER_NAME " = "
Tim Murray3a38b742014-07-02 10:41:08 -07002070 "new FieldPacker(" << mItemSizeof << " * getType().getX()/* count */);\n";
Jason Samscedffd92010-12-16 15:29:49 -08002071
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002072 endFunction();
Zonr Changd42a4292010-10-17 02:38:43 +08002073}
2074
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002075/******************** Methods to generate type class /end ********************/
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002076
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002077/********** Methods to create Element in Java of given record type ***********/
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002078
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002079RSReflectionJavaElementBuilder::RSReflectionJavaElementBuilder(
2080 const char *ElementBuilderName, const RSExportRecordType *ERT,
2081 const char *RenderScriptVar, GeneratedFile *Out, const RSContext *RSContext,
2082 RSReflectionJava *Reflection)
2083 : mElementBuilderName(ElementBuilderName), mERT(ERT),
2084 mRenderScriptVar(RenderScriptVar), mOut(Out), mPaddingFieldIndex(1),
2085 mRSContext(RSContext), mReflection(Reflection) {
2086 if (mRSContext->getTargetAPI() < SLANG_ICS_TARGET_API) {
2087 mPaddingPrefix = "#padding_";
2088 } else {
2089 mPaddingPrefix = "#rs_padding_";
2090 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002091}
2092
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002093void RSReflectionJavaElementBuilder::generate() {
2094 mOut->indent() << "Element.Builder " << mElementBuilderName
2095 << " = new Element.Builder(" << mRenderScriptVar << ");\n";
2096 genAddElement(mERT, "", /* ArraySize = */ 0);
2097}
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002098
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002099void RSReflectionJavaElementBuilder::genAddElement(const RSExportType *ET,
2100 const std::string &VarName,
2101 unsigned ArraySize) {
Stephen Hines47aca4e2012-03-08 20:07:28 -08002102 std::string ElementConstruct = GetBuiltinElementConstruct(ET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002103
Stephen Hines47aca4e2012-03-08 20:07:28 -08002104 if (ElementConstruct != "") {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002105 genAddStatementStart();
2106 *mOut << ElementConstruct << "(" << mRenderScriptVar << ")";
2107 genAddStatementEnd(VarName, ArraySize);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002108 } else {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002109
2110 switch (ET->getClass()) {
2111 case RSExportType::ExportClassPrimitive: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002112 const RSExportPrimitiveType *EPT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07002113 static_cast<const RSExportPrimitiveType *>(ET);
Stephen Hines47aca4e2012-03-08 20:07:28 -08002114 const char *DataTypeName =
2115 RSExportPrimitiveType::getRSReflectionType(EPT)->rs_type;
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002116 genAddStatementStart();
2117 *mOut << "Element.createUser(" << mRenderScriptVar
2118 << ", Element.DataType." << DataTypeName << ")";
2119 genAddStatementEnd(VarName, ArraySize);
2120 break;
2121 }
2122 case RSExportType::ExportClassVector: {
2123 const RSExportVectorType *EVT =
2124 static_cast<const RSExportVectorType *>(ET);
2125 const char *DataTypeName =
2126 RSExportPrimitiveType::getRSReflectionType(EVT)->rs_type;
2127 genAddStatementStart();
2128 *mOut << "Element.createVector(" << mRenderScriptVar
2129 << ", Element.DataType." << DataTypeName << ", "
2130 << EVT->getNumElement() << ")";
2131 genAddStatementEnd(VarName, ArraySize);
2132 break;
2133 }
2134 case RSExportType::ExportClassPointer:
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002135 // Pointer type variable should be resolved in
2136 // GetBuiltinElementConstruct()
Stephen Hines6e6578a2011-02-07 18:05:48 -08002137 slangAssert(false && "??");
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002138 break;
2139 case RSExportType::ExportClassMatrix:
Zonr Chang92b344a2010-10-05 20:39:03 +08002140 // Matrix type variable should be resolved
2141 // in GetBuiltinElementConstruct()
Stephen Hines6e6578a2011-02-07 18:05:48 -08002142 slangAssert(false && "??");
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002143 break;
2144 case RSExportType::ExportClassConstantArray: {
Zonr Chang2e1dba62010-10-05 22:20:11 +08002145 const RSExportConstantArrayType *ECAT =
2146 static_cast<const RSExportConstantArrayType *>(ET);
Zonr Chang2e1dba62010-10-05 22:20:11 +08002147
Zonr Chang89273bd2010-10-14 20:57:38 +08002148 const RSExportType *ElementType = ECAT->getElementType();
2149 if (ElementType->getClass() != RSExportType::ExportClassRecord) {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002150 genAddElement(ECAT->getElementType(), VarName, ECAT->getSize());
Zonr Chang89273bd2010-10-14 20:57:38 +08002151 } else {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002152 std::string NewElementBuilderName(mElementBuilderName);
Zonr Chang89273bd2010-10-14 20:57:38 +08002153 NewElementBuilderName.append(1, '_');
Zonr Chang2e1dba62010-10-05 22:20:11 +08002154
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002155 RSReflectionJavaElementBuilder builder(
2156 NewElementBuilderName.c_str(),
2157 static_cast<const RSExportRecordType *>(ElementType),
2158 mRenderScriptVar, mOut, mRSContext, mReflection);
2159 builder.generate();
2160
Zonr Chang89273bd2010-10-14 20:57:38 +08002161 ArraySize = ECAT->getSize();
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002162 genAddStatementStart();
2163 *mOut << NewElementBuilderName << ".create()";
2164 genAddStatementEnd(VarName, ArraySize);
Zonr Chang89273bd2010-10-14 20:57:38 +08002165 }
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002166 break;
2167 }
2168 case RSExportType::ExportClassRecord: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002169 // Simalar to case of RSExportType::ExportClassRecord in genPackVarOfType.
2170 //
zonr6315f762010-10-05 15:35:14 +08002171 // TODO(zonr): Generalize these two function such that there's no
2172 // duplicated codes.
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002173 const RSExportRecordType *ERT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07002174 static_cast<const RSExportRecordType *>(ET);
2175 int Pos = 0; // relative pos from now on
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002176
2177 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07002178 E = ERT->fields_end();
2179 I != E; I++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002180 const RSExportRecordType::Field *F = *I;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002181 int FieldOffset = F->getOffsetInParent();
Jean-Luc Brouilletc95381a2014-05-14 21:24:45 -07002182 const RSExportType *T = F->getType();
2183 int FieldStoreSize = T->getStoreSize();
2184 int FieldAllocSize = T->getAllocSize();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002185
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002186 std::string FieldName;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002187 if (!VarName.empty())
2188 FieldName = VarName + "." + F->getName();
2189 else
2190 FieldName = F->getName();
2191
2192 // Alignment
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002193 genAddPadding(FieldOffset - Pos);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002194
2195 // eb.add(...)
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002196 mReflection->addFieldIndexMapping(F);
Zonr Chang89273bd2010-10-14 20:57:38 +08002197 if (F->getType()->getClass() != RSExportType::ExportClassRecord) {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002198 genAddElement(F->getType(), FieldName, 0);
Zonr Chang89273bd2010-10-14 20:57:38 +08002199 } else {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002200 std::string NewElementBuilderName(mElementBuilderName);
Zonr Chang89273bd2010-10-14 20:57:38 +08002201 NewElementBuilderName.append(1, '_');
2202
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002203 RSReflectionJavaElementBuilder builder(
2204 NewElementBuilderName.c_str(),
2205 static_cast<const RSExportRecordType *>(F->getType()),
2206 mRenderScriptVar, mOut, mRSContext, mReflection);
2207 builder.generate();
Zonr Chang89273bd2010-10-14 20:57:38 +08002208
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002209 genAddStatementStart();
2210 *mOut << NewElementBuilderName << ".create()";
2211 genAddStatementEnd(FieldName, ArraySize);
Zonr Chang89273bd2010-10-14 20:57:38 +08002212 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002213
Stephen Hinesa9ae5ae2011-11-11 21:16:59 -08002214 if (mRSContext->getTargetAPI() < SLANG_ICS_TARGET_API) {
2215 // There is padding within the field type. This is only necessary
2216 // for HC-targeted APIs.
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002217 genAddPadding(FieldAllocSize - FieldStoreSize);
Stephen Hinesa9ae5ae2011-11-11 21:16:59 -08002218 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002219
2220 Pos = FieldOffset + FieldAllocSize;
2221 }
2222
2223 // There maybe some padding after the struct
Jean-Luc Brouilletc95381a2014-05-14 21:24:45 -07002224 size_t RecordAllocSize = ERT->getAllocSize();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002225
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002226 genAddPadding(RecordAllocSize - Pos);
2227 break;
2228 }
2229 default:
Stephen Hines6e6578a2011-02-07 18:05:48 -08002230 slangAssert(false && "Unknown class of type");
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002231 break;
Shih-wei Liaob1a28e72010-06-16 16:31:32 -07002232 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002233 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002234}
2235
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002236void RSReflectionJavaElementBuilder::genAddPadding(int PaddingSize) {
2237 while (PaddingSize > 0) {
2238 const std::string &VarName = createPaddingField();
2239 genAddStatementStart();
2240 if (PaddingSize >= 4) {
2241 *mOut << "Element.U32(" << mRenderScriptVar << ")";
2242 PaddingSize -= 4;
2243 } else if (PaddingSize >= 2) {
2244 *mOut << "Element.U16(" << mRenderScriptVar << ")";
2245 PaddingSize -= 2;
2246 } else if (PaddingSize >= 1) {
2247 *mOut << "Element.U8(" << mRenderScriptVar << ")";
2248 PaddingSize -= 1;
2249 }
2250 genAddStatementEnd(VarName, 0);
2251 }
2252}
2253
2254void RSReflectionJavaElementBuilder::genAddStatementStart() {
2255 mOut->indent() << mElementBuilderName << ".add(";
2256}
2257
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07002258void
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002259RSReflectionJavaElementBuilder::genAddStatementEnd(const std::string &VarName,
2260 unsigned ArraySize) {
2261 *mOut << ", \"" << VarName << "\"";
2262 if (ArraySize > 0) {
2263 *mOut << ", " << ArraySize;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002264 }
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07002265 *mOut << ");\n";
2266 // TODO Review incFieldIndex. It's probably better to assign the numbers at
2267 // the start rather
2268 // than as we're generating the code.
2269 mReflection->incFieldIndex();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002270}
2271
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002272/******** Methods to create Element in Java of given record type /end ********/
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002273
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -07002274bool RSReflectionJava::reflect() {
2275 std::string ErrorMsg;
2276 if (!genScriptClass(mScriptClassName, ErrorMsg)) {
2277 std::cerr << "Failed to generate class " << mScriptClassName << " ("
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002278 << ErrorMsg << ")\n";
2279 return false;
2280 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002281
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -07002282 mGeneratedFileNames->push_back(mScriptClassName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002283
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002284 // class ScriptField_<TypeName>
2285 for (RSContext::const_export_type_iterator
2286 TI = mRSContext->export_types_begin(),
2287 TE = mRSContext->export_types_end();
2288 TI != TE; TI++) {
2289 const RSExportType *ET = TI->getValue();
2290
2291 if (ET->getClass() == RSExportType::ExportClassRecord) {
2292 const RSExportRecordType *ERT =
2293 static_cast<const RSExportRecordType *>(ET);
2294
2295 if (!ERT->isArtificial() && !genTypeClass(ERT, ErrorMsg)) {
2296 std::cerr << "Failed to generate type class for struct '"
2297 << ERT->getName() << "' (" << ErrorMsg << ")\n";
2298 return false;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002299 }
2300 }
2301 }
2302
2303 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002304}
2305
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002306const char *RSReflectionJava::AccessModifierStr(AccessModifier AM) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002307 switch (AM) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07002308 case AM_Public:
2309 return "public";
2310 break;
2311 case AM_Protected:
2312 return "protected";
2313 break;
2314 case AM_Private:
2315 return "private";
2316 break;
2317 case AM_PublicSynchronized:
2318 return "public synchronized";
2319 break;
2320 default:
2321 return "";
2322 break;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002323 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002324}
2325
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002326bool RSReflectionJava::startClass(AccessModifier AM, bool IsStatic,
2327 const std::string &ClassName,
2328 const char *SuperClassName,
2329 std::string &ErrorMsg) {
Zonr Chang8c6d9b22010-10-07 18:01:19 +08002330 // Open file for class
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002331 std::string FileName = ClassName + ".java";
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -07002332 if (!mOut.startFile(mOutputDirectory, FileName, mRSSourceFileName,
Stephen Hinesfc4f78b2014-06-10 18:07:10 -07002333 mRSContext->getLicenseNote(), true,
2334 mRSContext->getVerbose())) {
Zonr Chang8c6d9b22010-10-07 18:01:19 +08002335 return false;
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002336 }
Ying Wang4e348442010-08-18 10:29:12 -07002337
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002338 // Package
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002339 if (!mPackageName.empty()) {
2340 mOut << "package " << mPackageName << ";\n";
2341 }
2342 mOut << "\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002343
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002344 // Imports
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002345 mOut << "import " << mRSPackageName << ".*;\n";
Stephen Hines44d495d2014-05-22 19:42:55 -07002346 if (getEmbedBitcodeInJava()) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002347 mOut << "import " << mPackageName << "."
Stephen Hines44d495d2014-05-22 19:42:55 -07002348 << RSSlangReflectUtils::JavaBitcodeClassNameFromRSFileName(
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -07002349 mRSSourceFileName.c_str()) << ";\n";
Stephen Hines44d495d2014-05-22 19:42:55 -07002350 } else {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002351 mOut << "import android.content.res.Resources;\n";
Stephen Hines44d495d2014-05-22 19:42:55 -07002352 }
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002353 mOut << "\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002354
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002355 // All reflected classes should be annotated as hidden, so that they won't
2356 // be exposed in SDK.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002357 mOut << "/**\n";
2358 mOut << " * @hide\n";
2359 mOut << " */\n";
Ying Wang4e348442010-08-18 10:29:12 -07002360
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002361 mOut << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class "
2362 << ClassName;
Chris Wailes5abbe0e2014-08-12 15:58:29 -07002363 if (SuperClassName != nullptr)
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002364 mOut << " extends " << SuperClassName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002365
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002366 mOut.startBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002367
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002368 mClassName = ClassName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002369
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002370 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002371}
2372
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002373void RSReflectionJava::endClass() {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002374 mOut.endBlock();
2375 mOut.closeFile();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002376 clear();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002377}
2378
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002379void RSReflectionJava::startTypeClass(const std::string &ClassName) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002380 mOut.indent() << "public static class " << ClassName;
2381 mOut.startBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002382}
2383
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002384void RSReflectionJava::endTypeClass() { mOut.endBlock(); }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002385
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002386void RSReflectionJava::startFunction(AccessModifier AM, bool IsStatic,
2387 const char *ReturnType,
2388 const std::string &FunctionName, int Argc,
2389 ...) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002390 ArgTy Args;
2391 va_list vl;
2392 va_start(vl, Argc);
2393
zonr6315f762010-10-05 15:35:14 +08002394 for (int i = 0; i < Argc; i++) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07002395 const char *ArgType = va_arg(vl, const char *);
2396 const char *ArgName = va_arg(vl, const char *);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002397
zonr6315f762010-10-05 15:35:14 +08002398 Args.push_back(std::make_pair(ArgType, ArgName));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002399 }
2400 va_end(vl);
2401
2402 startFunction(AM, IsStatic, ReturnType, FunctionName, Args);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002403}
2404
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002405void RSReflectionJava::startFunction(AccessModifier AM, bool IsStatic,
2406 const char *ReturnType,
2407 const std::string &FunctionName,
2408 const ArgTy &Args) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002409 mOut.indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ")
2410 << ((ReturnType) ? ReturnType : "") << " " << FunctionName
2411 << "(";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002412
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002413 bool FirstArg = true;
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07002414 for (ArgTy::const_iterator I = Args.begin(), E = Args.end(); I != E; I++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002415 if (!FirstArg)
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002416 mOut << ", ";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002417 else
2418 FirstArg = false;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002419
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002420 mOut << I->first << " " << I->second;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002421 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002422
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002423 mOut << ")";
2424 mOut.startBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002425}
2426
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002427void RSReflectionJava::endFunction() { mOut.endBlock(); }
Stephen Hinese639eb52010-11-08 19:27:20 -08002428
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002429bool RSReflectionJava::addTypeNameForElement(const std::string &TypeName) {
Stephen Hines1f6c3312012-07-03 17:23:33 -07002430 if (mTypesToCheck.find(TypeName) == mTypesToCheck.end()) {
2431 mTypesToCheck.insert(TypeName);
2432 return true;
2433 } else {
2434 return false;
2435 }
2436}
2437
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002438bool RSReflectionJava::addTypeNameForFieldPacker(const std::string &TypeName) {
Stephen Hines1f6c3312012-07-03 17:23:33 -07002439 if (mFieldPackerTypes.find(TypeName) == mFieldPackerTypes.end()) {
2440 mFieldPackerTypes.insert(TypeName);
2441 return true;
2442 } else {
2443 return false;
2444 }
2445}
2446
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07002447} // namespace slang