blob: 9f5ccd0a7d12ea14f95261f978b1a1708e41e16c [file] [log] [blame]
Tim Murray3a38b742014-07-02 10:41:08 -07001
Zonr Changc383a502010-10-12 01:52:08 +08002/*
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07003 * Copyright 2010-2014, The Android Open Source Project
Zonr Changc383a502010-10-12 01:52:08 +08004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
zonr6315f762010-10-05 15:35:14 +080018#include "slang_rs_reflection.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070019
Stephen Hinese639eb52010-11-08 19:27:20 -080020#include <sys/stat.h>
21
Shih-wei Liao462aefd2010-06-04 15:32:04 -070022#include <cstdarg>
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070023#include <cctype>
Stephen Hinese639eb52010-11-08 19:27:20 -080024
25#include <algorithm>
Stephen Hinesd369cda2012-02-13 12:00:03 -080026#include <sstream>
Stephen Hinese639eb52010-11-08 19:27:20 -080027#include <string>
28#include <utility>
Shih-wei Liao462aefd2010-06-04 15:32:04 -070029
zonr6315f762010-10-05 15:35:14 +080030#include "llvm/ADT/APFloat.h"
Zonr Chang89273bd2010-10-14 20:57:38 +080031#include "llvm/ADT/StringExtras.h"
zonr6315f762010-10-05 15:35:14 +080032
Raphael8d5a2f62011-02-08 00:15:05 -080033#include "os_sep.h"
zonr6315f762010-10-05 15:35:14 +080034#include "slang_rs_context.h"
35#include "slang_rs_export_var.h"
Stephen Hines593a8942011-05-10 15:29:50 -070036#include "slang_rs_export_foreach.h"
zonr6315f762010-10-05 15:35:14 +080037#include "slang_rs_export_func.h"
38#include "slang_rs_reflect_utils.h"
Stephen Hines4cc499d2011-08-24 19:06:17 -070039#include "slang_version.h"
Stephen Hinese639eb52010-11-08 19:27:20 -080040#include "slang_utils.h"
zonr6315f762010-10-05 15:35:14 +080041
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070042#define RS_SCRIPT_CLASS_NAME_PREFIX "ScriptC_"
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070043#define RS_SCRIPT_CLASS_SUPER_CLASS_NAME "ScriptC"
Shih-wei Liao8b1d0dd2010-07-15 18:56:55 -070044
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070045#define RS_TYPE_CLASS_SUPER_CLASS_NAME ".Script.FieldBase"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070046
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070047#define RS_TYPE_ITEM_CLASS_NAME "Item"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070048
Tim Murray3a38b742014-07-02 10:41:08 -070049#define RS_TYPE_ITEM_SIZEOF_LEGACY "Item.sizeof"
50#define RS_TYPE_ITEM_SIZEOF_CURRENT "mElement.getBytesSize()"
51
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070052#define RS_TYPE_ITEM_BUFFER_NAME "mItemArray"
53#define RS_TYPE_ITEM_BUFFER_PACKER_NAME "mIOBuffer"
54#define RS_TYPE_ELEMENT_REF_NAME "mElementCache"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070055
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070056#define RS_EXPORT_VAR_INDEX_PREFIX "mExportVarIdx_"
57#define RS_EXPORT_VAR_PREFIX "mExportVar_"
58#define RS_EXPORT_VAR_ELEM_PREFIX "mExportVarElem_"
59#define RS_EXPORT_VAR_DIM_PREFIX "mExportVarDim_"
60#define RS_EXPORT_VAR_CONST_PREFIX "const_"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070061
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070062#define RS_ELEM_PREFIX "__"
Stephen Hinesa6b54142012-04-09 18:25:08 -070063
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070064#define RS_FP_PREFIX "__rs_fp_"
Stephen Hines1f6c3312012-07-03 17:23:33 -070065
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070066#define RS_RESOURCE_NAME "__rs_resource_name"
Stephen Hinesd2936932012-09-12 20:44:32 -070067
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070068#define RS_EXPORT_FUNC_INDEX_PREFIX "mExportFuncIdx_"
69#define RS_EXPORT_FOREACH_INDEX_PREFIX "mExportForEachIdx_"
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
Stephen Hinese639eb52010-11-08 19:27:20 -080074namespace slang {
Shih-wei Liao462aefd2010-06-04 15:32:04 -070075
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -070076class RSReflectionJavaElementBuilder {
77public:
78 RSReflectionJavaElementBuilder(const char *ElementBuilderName,
79 const RSExportRecordType *ERT,
80 const char *RenderScriptVar,
81 GeneratedFile *Out, const RSContext *RSContext,
82 RSReflectionJava *Reflection);
83 void generate();
84
85private:
86 void genAddElement(const RSExportType *ET, const std::string &VarName,
87 unsigned ArraySize);
88 void genAddStatementStart();
89 void genAddStatementEnd(const std::string &VarName, unsigned ArraySize);
90 void genAddPadding(int PaddingSize);
91 // TODO Will remove later due to field name information is not necessary for
92 // C-reflect-to-Java
93 std::string createPaddingField() {
94 return mPaddingPrefix + llvm::itostr(mPaddingFieldIndex++);
95 }
96
97 const char *mElementBuilderName;
98 const RSExportRecordType *mERT;
99 const char *mRenderScriptVar;
100 GeneratedFile *mOut;
101 std::string mPaddingPrefix;
102 int mPaddingFieldIndex;
103 const RSContext *mRSContext;
104 RSReflectionJava *mReflection;
105};
106
Zonr Chang92b344a2010-10-05 20:39:03 +0800107static const char *GetMatrixTypeName(const RSExportMatrixType *EMT) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700108 static const char *MatrixTypeJavaNameMap[] = {/* 2x2 */ "Matrix2f",
109 /* 3x3 */ "Matrix3f",
110 /* 4x4 */ "Matrix4f",
Zonr Chang92b344a2010-10-05 20:39:03 +0800111 };
112 unsigned Dim = EMT->getDim();
113
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700114 if ((Dim - 2) < (sizeof(MatrixTypeJavaNameMap) / sizeof(const char *)))
115 return MatrixTypeJavaNameMap[EMT->getDim() - 2];
Zonr Chang92b344a2010-10-05 20:39:03 +0800116
Stephen Hines6e6578a2011-02-07 18:05:48 -0800117 slangAssert(false && "GetMatrixTypeName : Unsupported matrix dimension");
Zonr Chang92b344a2010-10-05 20:39:03 +0800118 return NULL;
119}
120
Stephen Hines6e6578a2011-02-07 18:05:48 -0800121static const char *GetVectorAccessor(unsigned Index) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700122 static const char *VectorAccessorMap[] = {/* 0 */ "x",
123 /* 1 */ "y",
124 /* 2 */ "z",
125 /* 3 */ "w",
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700126 };
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700127
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700128 slangAssert((Index < (sizeof(VectorAccessorMap) / sizeof(const char *))) &&
Stephen Hines6e6578a2011-02-07 18:05:48 -0800129 "Out-of-bound index to access vector member");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700130
131 return VectorAccessorMap[Index];
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700132}
133
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700134static const char *GetPackerAPIName(const RSExportPrimitiveType *EPT) {
zonr6315f762010-10-05 15:35:14 +0800135 static const char *PrimitiveTypePackerAPINameMap[] = {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700136 "", // DataTypeFloat16
137 "addF32", // DataTypeFloat32
138 "addF64", // DataTypeFloat64
139 "addI8", // DataTypeSigned8
140 "addI16", // DataTypeSigned16
141 "addI32", // DataTypeSigned32
142 "addI64", // DataTypeSigned64
143 "addU8", // DataTypeUnsigned8
144 "addU16", // DataTypeUnsigned16
145 "addU32", // DataTypeUnsigned32
146 "addU64", // DataTypeUnsigned64
147 "addBoolean", // DataTypeBoolean
148 "addU16", // DataTypeUnsigned565
149 "addU16", // DataTypeUnsigned5551
150 "addU16", // DataTypeUnsigned4444
151 "addMatrix", // DataTypeRSMatrix2x2
152 "addMatrix", // DataTypeRSMatrix3x3
153 "addMatrix", // DataTypeRSMatrix4x4
154 "addObj", // DataTypeRSElement
155 "addObj", // DataTypeRSType
156 "addObj", // DataTypeRSAllocation
157 "addObj", // DataTypeRSSampler
158 "addObj", // DataTypeRSScript
159 "addObj", // DataTypeRSMesh
160 "addObj", // DataTypeRSPath
161 "addObj", // DataTypeRSProgramFragment
162 "addObj", // DataTypeRSProgramVertex
163 "addObj", // DataTypeRSProgramRaster
164 "addObj", // DataTypeRSProgramStore
165 "addObj", // DataTypeRSFont
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700166 };
167 unsigned TypeId = EPT->getType();
168
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700169 if (TypeId < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char *)))
170 return PrimitiveTypePackerAPINameMap[EPT->getType()];
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700171
Stephen Hines6e6578a2011-02-07 18:05:48 -0800172 slangAssert(false && "GetPackerAPIName : Unknown primitive data type");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700173 return NULL;
174}
175
Stephen Hinesd369cda2012-02-13 12:00:03 -0800176static std::string GetTypeName(const RSExportType *ET, bool Brackets = true) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700177 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700178 case RSExportType::ExportClassPrimitive: {
179 return RSExportPrimitiveType::getRSReflectionType(
180 static_cast<const RSExportPrimitiveType *>(ET))->java_name;
181 }
182 case RSExportType::ExportClassPointer: {
183 const RSExportType *PointeeType =
184 static_cast<const RSExportPointerType *>(ET)->getPointeeType();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700185
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700186 if (PointeeType->getClass() != RSExportType::ExportClassRecord)
187 return "Allocation";
188 else
189 return PointeeType->getElementName();
190 }
191 case RSExportType::ExportClassVector: {
192 const RSExportVectorType *EVT = static_cast<const RSExportVectorType *>(ET);
193 std::stringstream VecName;
194 VecName << EVT->getRSReflectionType(EVT)->rs_java_vector_prefix
195 << EVT->getNumElement();
196 return VecName.str();
197 }
198 case RSExportType::ExportClassMatrix: {
199 return GetMatrixTypeName(static_cast<const RSExportMatrixType *>(ET));
200 }
201 case RSExportType::ExportClassConstantArray: {
202 const RSExportConstantArrayType *CAT =
203 static_cast<const RSExportConstantArrayType *>(ET);
204 std::string ElementTypeName = GetTypeName(CAT->getElementType());
205 if (Brackets) {
206 ElementTypeName.append("[]");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700207 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700208 return ElementTypeName;
209 }
210 case RSExportType::ExportClassRecord: {
211 return ET->getElementName() + "." RS_TYPE_ITEM_CLASS_NAME;
212 }
213 default: { slangAssert(false && "Unknown class of type"); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700214 }
215
216 return "";
217}
218
Shih-wei Liaocf950c42010-10-06 03:44:40 -0700219static const char *GetTypeNullValue(const RSExportType *ET) {
220 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700221 case RSExportType::ExportClassPrimitive: {
222 const RSExportPrimitiveType *EPT =
223 static_cast<const RSExportPrimitiveType *>(ET);
224 if (EPT->isRSObjectType())
Shih-wei Liaocf950c42010-10-06 03:44:40 -0700225 return "null";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700226 else if (EPT->getType() == DataTypeBoolean)
227 return "false";
228 else
229 return "0";
230 break;
231 }
232 case RSExportType::ExportClassPointer:
233 case RSExportType::ExportClassVector:
234 case RSExportType::ExportClassMatrix:
235 case RSExportType::ExportClassConstantArray:
236 case RSExportType::ExportClassRecord: {
237 return "null";
238 break;
239 }
240 default: { slangAssert(false && "Unknown class of type"); }
Shih-wei Liaocf950c42010-10-06 03:44:40 -0700241 }
242 return "";
243}
244
Stephen Hines47aca4e2012-03-08 20:07:28 -0800245static std::string GetBuiltinElementConstruct(const RSExportType *ET) {
Zonr Chang2e1dba62010-10-05 22:20:11 +0800246 if (ET->getClass() == RSExportType::ExportClassPrimitive) {
Stephen Hinesa6b54142012-04-09 18:25:08 -0700247 return std::string("Element.") + ET->getElementName();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700248 } else if (ET->getClass() == RSExportType::ExportClassVector) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700249 const RSExportVectorType *EVT = static_cast<const RSExportVectorType *>(ET);
Jean-Luc Brouilletcec9b652014-05-14 19:33:57 -0700250 if (EVT->getType() == DataTypeFloat32) {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -0700251 if (EVT->getNumElement() == 2) {
Stephen Hines2b8fb642012-03-09 00:12:47 -0800252 return "Element.F32_2";
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -0700253 } else if (EVT->getNumElement() == 3) {
Stephen Hines2b8fb642012-03-09 00:12:47 -0800254 return "Element.F32_3";
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -0700255 } else if (EVT->getNumElement() == 4) {
Stephen Hines2b8fb642012-03-09 00:12:47 -0800256 return "Element.F32_4";
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -0700257 } else {
258 slangAssert(false && "Vectors should be size 2, 3, 4");
259 }
Jean-Luc Brouilletcec9b652014-05-14 19:33:57 -0700260 } else if (EVT->getType() == DataTypeUnsigned8) {
Stephen Hines2b8fb642012-03-09 00:12:47 -0800261 if (EVT->getNumElement() == 4)
262 return "Element.U8_4";
Shih-wei Liao324c0472010-06-21 13:15:11 -0700263 }
Zonr Chang92b344a2010-10-05 20:39:03 +0800264 } else if (ET->getClass() == RSExportType::ExportClassMatrix) {
265 const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType *>(ET);
266 switch (EMT->getDim()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700267 case 2:
268 return "Element.MATRIX_2X2";
269 case 3:
270 return "Element.MATRIX_3X3";
271 case 4:
272 return "Element.MATRIX_4X4";
273 default:
274 slangAssert(false && "Unsupported dimension of matrix");
Zonr Chang92b344a2010-10-05 20:39:03 +0800275 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700276 }
Stephen Hines47aca4e2012-03-08 20:07:28 -0800277 // RSExportType::ExportClassPointer can't be generated in a struct.
Shih-wei Liao324c0472010-06-21 13:15:11 -0700278
Stephen Hines47aca4e2012-03-08 20:07:28 -0800279 return "";
Stephen Hines48b72bf2011-06-10 15:37:27 -0700280}
281
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700282/********************** Methods to generate script class **********************/
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -0700283RSReflectionJava::RSReflectionJava(const RSContext *Context,
284 std::vector<std::string> *GeneratedFileNames,
285 const std::string &OutputBaseDirectory,
286 const std::string &RSSourceFileName,
287 const std::string &BitCodeFileName,
288 bool EmbedBitcodeInJava)
289 : mRSContext(Context), mPackageName(Context->getReflectJavaPackageName()),
290 mRSPackageName(Context->getRSPackageName()),
291 mOutputBaseDirectory(OutputBaseDirectory),
292 mRSSourceFileName(RSSourceFileName), mBitCodeFileName(BitCodeFileName),
293 mResourceId(RSSlangReflectUtils::JavaClassNameFromRSFileName(
294 mBitCodeFileName.c_str())),
295 mScriptClassName(RS_SCRIPT_CLASS_NAME_PREFIX +
296 RSSlangReflectUtils::JavaClassNameFromRSFileName(
297 mRSSourceFileName.c_str())),
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -0700298 mEmbedBitcodeInJava(EmbedBitcodeInJava), mNextExportVarSlot(0),
299 mNextExportFuncSlot(0), mNextExportForEachSlot(0), mLastError(""),
300 mGeneratedFileNames(GeneratedFileNames), mFieldIndex(0) {
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -0700301 slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames");
302 slangAssert(!mPackageName.empty() && mPackageName != "-");
303
304 mOutputDirectory = RSSlangReflectUtils::ComputePackagedPath(
305 OutputBaseDirectory.c_str(), mPackageName.c_str()) +
306 OS_PATH_SEPARATOR_STR;
Tim Murray3a38b742014-07-02 10:41:08 -0700307
308 // mElement.getBytesSize only exists on JB+
309 if (mRSContext->getTargetAPI() >= SLANG_JB_TARGET_API) {
310 mItemSizeof = RS_TYPE_ITEM_SIZEOF_CURRENT;
311 } else {
312 mItemSizeof = RS_TYPE_ITEM_SIZEOF_LEGACY;
313 }
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -0700314}
315
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700316bool RSReflectionJava::genScriptClass(const std::string &ClassName,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -0700317 std::string &ErrorMsg) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700318 if (!startClass(AM_Public, false, ClassName, RS_SCRIPT_CLASS_SUPER_CLASS_NAME,
319 ErrorMsg))
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700320 return false;
321
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700322 genScriptClassConstructor();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700323
324 // Reflect export variable
325 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700326 E = mRSContext->export_vars_end();
327 I != E; I++)
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700328 genExportVariable(*I);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700329
Stephen Hines4a4bf922011-08-18 17:20:33 -0700330 // Reflect export for each functions (only available on ICS+)
Stephen Hines4cc499d2011-08-24 19:06:17 -0700331 if (mRSContext->getTargetAPI() >= SLANG_ICS_TARGET_API) {
Stephen Hines4a4bf922011-08-18 17:20:33 -0700332 for (RSContext::const_export_foreach_iterator
333 I = mRSContext->export_foreach_begin(),
334 E = mRSContext->export_foreach_end();
335 I != E; I++)
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700336 genExportForEach(*I);
Stephen Hines4a4bf922011-08-18 17:20:33 -0700337 }
Stephen Hines593a8942011-05-10 15:29:50 -0700338
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700339 // Reflect export function
340 for (RSContext::const_export_func_iterator
341 I = mRSContext->export_funcs_begin(),
342 E = mRSContext->export_funcs_end();
343 I != E; I++)
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700344 genExportFunction(*I);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700345
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700346 endClass();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700347
348 return true;
349}
350
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700351void RSReflectionJava::genScriptClassConstructor() {
Stephen Hines4c8b6592014-05-22 20:18:45 -0700352 std::string className(RSSlangReflectUtils::JavaBitcodeClassNameFromRSFileName(
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -0700353 mRSSourceFileName.c_str()));
Stephen Hinesd2936932012-09-12 20:44:32 -0700354 // Provide a simple way to reference this object.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700355 mOut.indent() << "private static final String " RS_RESOURCE_NAME " = \""
356 << getResourceId() << "\";\n";
Stephen Hinesd2936932012-09-12 20:44:32 -0700357
358 // Generate a simple constructor with only a single parameter (the rest
359 // can be inferred from information we already have).
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700360 mOut.indent() << "// Constructor\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700361 startFunction(AM_Public, false, NULL, getClassName(), 1, "RenderScript",
362 "rs");
Stephen Hines44d495d2014-05-22 19:42:55 -0700363
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700364 if (getEmbedBitcodeInJava()) {
Stephen Hines4c8b6592014-05-22 20:18:45 -0700365 // Call new single argument Java-only constructor
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700366 mOut.indent() << "super(rs,\n";
367 mOut.indent() << " " << RS_RESOURCE_NAME ",\n";
368 mOut.indent() << " " << className << ".getBitCode32(),\n";
Stephen Hines9ae18b22014-06-10 23:53:00 -0700369 mOut.indent() << " " << className << ".getBitCode64());\n";
Stephen Hines4c8b6592014-05-22 20:18:45 -0700370 } else {
371 // Call alternate constructor with required parameters.
372 // Look up the proper raw bitcode resource id via the context.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700373 mOut.indent() << "this(rs,\n";
374 mOut.indent() << " rs.getApplicationContext().getResources(),\n";
375 mOut.indent() << " rs.getApplicationContext().getResources()."
376 "getIdentifier(\n";
377 mOut.indent() << " " RS_RESOURCE_NAME ", \"raw\",\n";
378 mOut.indent()
379 << " rs.getApplicationContext().getPackageName()));\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700380 endFunction();
Stephen Hinesd2936932012-09-12 20:44:32 -0700381
Stephen Hines4c8b6592014-05-22 20:18:45 -0700382 // Alternate constructor (legacy) with 3 original parameters.
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700383 startFunction(AM_Public, false, NULL, getClassName(), 3, "RenderScript",
384 "rs", "Resources", "resources", "int", "id");
Stephen Hines4c8b6592014-05-22 20:18:45 -0700385 // Call constructor of super class
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700386 mOut.indent() << "super(rs, resources, id);\n";
Stephen Hines4c8b6592014-05-22 20:18:45 -0700387 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700388
389 // If an exported variable has initial value, reflect it
390
391 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700392 E = mRSContext->export_vars_end();
393 I != E; I++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700394 const RSExportVar *EV = *I;
Stephen Hinesd369cda2012-02-13 12:00:03 -0800395 if (!EV->getInit().isUninit()) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700396 genInitExportVariable(EV->getType(), EV->getName(), EV->getInit());
Stephen Hinesd369cda2012-02-13 12:00:03 -0800397 } else if (EV->getArraySize()) {
398 // Always create an initial zero-init array object.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700399 mOut.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = new "
400 << GetTypeName(EV->getType(), false) << "["
401 << EV->getArraySize() << "];\n";
Stephen Hinesd369cda2012-02-13 12:00:03 -0800402 size_t NumInits = EV->getNumInits();
403 const RSExportConstantArrayType *ECAT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700404 static_cast<const RSExportConstantArrayType *>(EV->getType());
Stephen Hinesd369cda2012-02-13 12:00:03 -0800405 const RSExportType *ET = ECAT->getElementType();
406 for (size_t i = 0; i < NumInits; i++) {
407 std::stringstream Name;
408 Name << EV->getName() << "[" << i << "]";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700409 genInitExportVariable(ET, Name.str(), EV->getInitArray(i));
Stephen Hinesd369cda2012-02-13 12:00:03 -0800410 }
411 }
Stephen Hinesa6b54142012-04-09 18:25:08 -0700412 if (mRSContext->getTargetAPI() >= SLANG_JB_TARGET_API) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700413 genTypeInstance(EV->getType());
Stephen Hinesa6b54142012-04-09 18:25:08 -0700414 }
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700415 genFieldPackerInstance(EV->getType());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700416 }
417
Stephen Hines48b72bf2011-06-10 15:37:27 -0700418 for (RSContext::const_export_foreach_iterator
419 I = mRSContext->export_foreach_begin(),
420 E = mRSContext->export_foreach_end();
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700421 I != E; I++) {
Stephen Hines48b72bf2011-06-10 15:37:27 -0700422 const RSExportForEach *EF = *I;
423
Chris Wailesc9454af2014-06-13 17:25:40 -0700424 const RSExportForEach::InTypeVec &InTypes = EF->getInTypes();
425 for (RSExportForEach::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
426 BI != EI; BI++) {
427
428 if (*BI != NULL) {
429 genTypeInstanceFromPointer(*BI);
430 }
Stephen Hines48b72bf2011-06-10 15:37:27 -0700431 }
Chris Wailesc9454af2014-06-13 17:25:40 -0700432
Stephen Hines48b72bf2011-06-10 15:37:27 -0700433 const RSExportType *OET = EF->getOutType();
434 if (OET) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700435 genTypeInstanceFromPointer(OET);
Stephen Hines48b72bf2011-06-10 15:37:27 -0700436 }
437 }
438
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700439 endFunction();
Jason Samsb6902e22010-11-03 17:04:06 -0700440
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700441 for (std::set<std::string>::iterator I = mTypesToCheck.begin(),
442 E = mTypesToCheck.end();
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700443 I != E; I++) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700444 mOut.indent() << "private Element " RS_ELEM_PREFIX << *I << ";\n";
Stephen Hines48b72bf2011-06-10 15:37:27 -0700445 }
446
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700447 for (std::set<std::string>::iterator I = mFieldPackerTypes.begin(),
448 E = mFieldPackerTypes.end();
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700449 I != E; I++) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700450 mOut.indent() << "private FieldPacker " RS_FP_PREFIX << *I << ";\n";
Stephen Hines1f6c3312012-07-03 17:23:33 -0700451 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700452}
453
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700454void RSReflectionJava::genInitBoolExportVariable(const std::string &VarName,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -0700455 const clang::APValue &Val) {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800456 slangAssert(!Val.isUninit() && "Not a valid initializer");
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700457 slangAssert((Val.getKind() == clang::APValue::Int) &&
458 "Bool type has wrong initial APValue");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700459
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700460 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700461
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700462 mOut << ((Val.getInt().getSExtValue() == 0) ? "false" : "true") << ";\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700463}
464
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700465void
466RSReflectionJava::genInitPrimitiveExportVariable(const std::string &VarName,
467 const clang::APValue &Val) {
Stephen Hines5d671782012-01-31 19:32:04 -0800468 slangAssert(!Val.isUninit() && "Not a valid initializer");
469
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700470 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -0700471 genInitValue(Val, false);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700472 mOut << ";\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700473}
474
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700475void RSReflectionJava::genInitExportVariable(const RSExportType *ET,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -0700476 const std::string &VarName,
477 const clang::APValue &Val) {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800478 slangAssert(!Val.isUninit() && "Not a valid initializer");
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700479
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700480 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700481 case RSExportType::ExportClassPrimitive: {
482 const RSExportPrimitiveType *EPT =
483 static_cast<const RSExportPrimitiveType *>(ET);
484 if (EPT->getType() == DataTypeBoolean) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700485 genInitBoolExportVariable(VarName, Val);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700486 } else {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700487 genInitPrimitiveExportVariable(VarName, Val);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700488 }
489 break;
490 }
491 case RSExportType::ExportClassPointer: {
492 if (!Val.isInt() || Val.getInt().getSExtValue() != 0)
493 std::cout << "Initializer which is non-NULL to pointer type variable "
494 "will be ignored\n";
495 break;
496 }
497 case RSExportType::ExportClassVector: {
498 const RSExportVectorType *EVT = static_cast<const RSExportVectorType *>(ET);
499 switch (Val.getKind()) {
500 case clang::APValue::Int:
501 case clang::APValue::Float: {
502 for (unsigned i = 0; i < EVT->getNumElement(); i++) {
503 std::string Name = VarName + "." + GetVectorAccessor(i);
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700504 genInitPrimitiveExportVariable(Name, Val);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700505 }
506 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700507 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700508 case clang::APValue::Vector: {
509 std::stringstream VecName;
510 VecName << EVT->getRSReflectionType(EVT)->rs_java_vector_prefix
511 << EVT->getNumElement();
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700512 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new "
513 << VecName.str() << "();\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700514
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700515 unsigned NumElements = std::min(
516 static_cast<unsigned>(EVT->getNumElement()), Val.getVectorLength());
517 for (unsigned i = 0; i < NumElements; i++) {
518 const clang::APValue &ElementVal = Val.getVectorElt(i);
519 std::string Name = VarName + "." + GetVectorAccessor(i);
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700520 genInitPrimitiveExportVariable(Name, ElementVal);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700521 }
522 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700523 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700524 case clang::APValue::MemberPointer:
525 case clang::APValue::Uninitialized:
526 case clang::APValue::ComplexInt:
527 case clang::APValue::ComplexFloat:
528 case clang::APValue::LValue:
529 case clang::APValue::Array:
530 case clang::APValue::Struct:
531 case clang::APValue::Union:
532 case clang::APValue::AddrLabelDiff: {
533 slangAssert(false && "Unexpected type of value of initializer.");
534 }
535 }
536 break;
537 }
538 // TODO(zonr): Resolving initializer of a record (and matrix) type variable
539 // is complex. It cannot obtain by just simply evaluating the initializer
540 // expression.
541 case RSExportType::ExportClassMatrix:
542 case RSExportType::ExportClassConstantArray:
543 case RSExportType::ExportClassRecord: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700544#if 0
545 unsigned InitIndex = 0;
zonr6315f762010-10-05 15:35:14 +0800546 const RSExportRecordType *ERT =
547 static_cast<const RSExportRecordType*>(ET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700548
Stephen Hines6e6578a2011-02-07 18:05:48 -0800549 slangAssert((Val.getKind() == clang::APValue::Vector) &&
550 "Unexpected type of initializer for record type variable");
Shih-wei Liao9c631ff2010-09-17 11:57:29 -0700551
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700552 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName
Stephen Hinesa6b54142012-04-09 18:25:08 -0700553 << " = new " << ERT->getElementName()
Jean-Luc Brouillet29689212014-05-27 13:25:31 -0700554 << "." RS_TYPE_ITEM_CLASS_NAME"();\n";
Shih-wei Liao9c631ff2010-09-17 11:57:29 -0700555
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700556 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
557 E = ERT->fields_end();
558 I != E;
559 I++) {
560 const RSExportRecordType::Field *F = *I;
561 std::string FieldName = VarName + "." + F->getName();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700562
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700563 if (InitIndex > Val.getVectorLength())
564 break;
565
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700566 genInitPrimitiveExportVariable(FieldName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700567 Val.getVectorElt(InitIndex++));
568 }
569#endif
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700570 slangAssert(false && "Unsupported initializer for record/matrix/constant "
571 "array type variable currently");
572 break;
573 }
574 default: { slangAssert(false && "Unknown class of type"); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700575 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700576}
577
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700578void RSReflectionJava::genExportVariable(const RSExportVar *EV) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700579 const RSExportType *ET = EV->getType();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700580
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700581 mOut.indent() << "private final static int " << RS_EXPORT_VAR_INDEX_PREFIX
582 << EV->getName() << " = " << getNextExportVarSlot() << ";\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700583
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700584 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700585 case RSExportType::ExportClassPrimitive: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700586 genPrimitiveTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700587 break;
588 }
589 case RSExportType::ExportClassPointer: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700590 genPointerTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700591 break;
592 }
593 case RSExportType::ExportClassVector: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700594 genVectorTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700595 break;
596 }
597 case RSExportType::ExportClassMatrix: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700598 genMatrixTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700599 break;
600 }
601 case RSExportType::ExportClassConstantArray: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700602 genConstantArrayTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700603 break;
604 }
605 case RSExportType::ExportClassRecord: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700606 genRecordTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700607 break;
608 }
609 default: { slangAssert(false && "Unknown class of type"); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700610 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700611}
612
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700613void RSReflectionJava::genExportFunction(const RSExportFunc *EF) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700614 mOut.indent() << "private final static int " << RS_EXPORT_FUNC_INDEX_PREFIX
615 << EF->getName() << " = " << getNextExportFuncSlot() << ";\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700616
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700617 // invoke_*()
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700618 ArgTy Args;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700619
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800620 if (EF->hasParam()) {
621 for (RSExportFunc::const_param_iterator I = EF->params_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700622 E = EF->params_end();
623 I != E; I++) {
624 Args.push_back(
625 std::make_pair(GetTypeName((*I)->getType()), (*I)->getName()));
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800626 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700627 }
628
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700629 startFunction(AM_Public, false, "void",
630 "invoke_" + EF->getName(/*Mangle=*/false),
631 // We are using un-mangled name since Java
632 // supports method overloading.
633 Args);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700634
635 if (!EF->hasParam()) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700636 mOut.indent() << "invoke(" << RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName()
637 << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700638 } else {
639 const RSExportRecordType *ERT = EF->getParamPacketType();
640 std::string FieldPackerName = EF->getName() + "_fp";
641
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700642 if (genCreateFieldPacker(ERT, FieldPackerName.c_str()))
643 genPackVarOfType(ERT, NULL, FieldPackerName.c_str());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700644
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700645 mOut.indent() << "invoke(" << RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName()
646 << ", " << FieldPackerName << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700647 }
648
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700649 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700650}
651
Chris Wailesc9454af2014-06-13 17:25:40 -0700652void RSReflectionJava::genPairwiseDimCheck(std::string name0,
653 std::string name1) {
654
655 mOut.indent() << "// Verify dimensions\n";
656 mOut.indent() << "t0 = " << name0 << ".getType();\n";
657 mOut.indent() << "t1 = " << name1 << ".getType();\n";
658 mOut.indent() << "if ((t0.getCount() != t1.getCount()) ||\n";
659 mOut.indent() << " (t0.getX() != t1.getX()) ||\n";
660 mOut.indent() << " (t0.getY() != t1.getY()) ||\n";
661 mOut.indent() << " (t0.getZ() != t1.getZ()) ||\n";
662 mOut.indent() << " (t0.hasFaces() != t1.hasFaces()) ||\n";
663 mOut.indent() << " (t0.hasMipmaps() != t1.hasMipmaps())) {\n";
664 mOut.indent() << " throw new RSRuntimeException(\"Dimension mismatch "
665 << "between parameters " << name0 << " and " << name1
666 << "!\");\n";
667 mOut.indent() << "}\n\n";
668}
669
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700670void RSReflectionJava::genExportForEach(const RSExportForEach *EF) {
Stephen Hinesc17e1982012-02-22 12:30:45 -0800671 if (EF->isDummyRoot()) {
672 // Skip reflection for dummy root() kernels. Note that we have to
673 // advance the next slot number for ForEach, however.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700674 mOut.indent() << "//private final static int "
675 << RS_EXPORT_FOREACH_INDEX_PREFIX << EF->getName() << " = "
676 << getNextExportForEachSlot() << ";\n";
Stephen Hinesc17e1982012-02-22 12:30:45 -0800677 return;
678 }
679
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700680 mOut.indent() << "private final static int " << RS_EXPORT_FOREACH_INDEX_PREFIX
681 << EF->getName() << " = " << getNextExportForEachSlot()
682 << ";\n";
Stephen Hines593a8942011-05-10 15:29:50 -0700683
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700684 // forEach_*()
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700685 ArgTy Args;
Stephen Hines593a8942011-05-10 15:29:50 -0700686
Stephen Hines9ca96e72012-09-13 16:57:06 -0700687 slangAssert(EF->getNumParameters() > 0 || EF->hasReturn());
Stephen Hines593a8942011-05-10 15:29:50 -0700688
Chris Wailesc9454af2014-06-13 17:25:40 -0700689 const RSExportForEach::InVec &Ins = EF->getIns();
690 const RSExportForEach::InTypeVec &InTypes = EF->getInTypes();
691 const RSExportType *OET = EF->getOutType();
692
693 if (Ins.size() == 1) {
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700694 Args.push_back(std::make_pair("Allocation", "ain"));
Chris Wailesc9454af2014-06-13 17:25:40 -0700695
696 } else if (Ins.size() > 1) {
697 for (RSExportForEach::InIter BI = Ins.begin(), EI = Ins.end(); BI != EI;
698 BI++) {
699
700 Args.push_back(std::make_pair("Allocation",
701 "ain_" + (*BI)->getName().str()));
702 }
703 }
704
Stephen Hines9ca96e72012-09-13 16:57:06 -0700705 if (EF->hasOut() || EF->hasReturn())
Stephen Hines593a8942011-05-10 15:29:50 -0700706 Args.push_back(std::make_pair("Allocation", "aout"));
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700707
708 const RSExportRecordType *ERT = EF->getParamPacketType();
709 if (ERT) {
710 for (RSExportForEach::const_param_iterator I = EF->params_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700711 E = EF->params_end();
712 I != E; I++) {
713 Args.push_back(
714 std::make_pair(GetTypeName((*I)->getType()), (*I)->getName()));
Stephen Hines593a8942011-05-10 15:29:50 -0700715 }
716 }
717
Tim Murrayb81a9932012-10-10 15:56:02 -0700718 if (mRSContext->getTargetAPI() >= SLANG_JB_MR1_TARGET_API) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700719 startFunction(AM_Public, false, "Script.KernelID",
720 "getKernelID_" + EF->getName(), 0);
Tim Murrayb81a9932012-10-10 15:56:02 -0700721
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700722 // TODO: add element checking
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700723 mOut.indent() << "return createKernelID(" << RS_EXPORT_FOREACH_INDEX_PREFIX
Chris Wailesc9454af2014-06-13 17:25:40 -0700724 << EF->getName() << ", " << EF->getSignatureMetadata()
725 << ", null, null);\n";
Tim Murrayb81a9932012-10-10 15:56:02 -0700726
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700727 endFunction();
Tim Murrayb81a9932012-10-10 15:56:02 -0700728 }
729
Stephen Hines50974742013-02-12 22:11:08 -0800730 if (mRSContext->getTargetAPI() >= SLANG_JB_MR2_TARGET_API) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700731 startFunction(AM_Public, false, "void", "forEach_" + EF->getName(), Args);
Stephen Hines50974742013-02-12 22:11:08 -0800732
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700733 mOut.indent() << "forEach_" << EF->getName();
734 mOut << "(";
Stephen Hines50974742013-02-12 22:11:08 -0800735
Chris Wailesc9454af2014-06-13 17:25:40 -0700736 if (Ins.size() == 1) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700737 mOut << "ain, ";
Chris Wailesc9454af2014-06-13 17:25:40 -0700738
739 } else if (Ins.size() > 1) {
740 for (RSExportForEach::InIter BI = Ins.begin(), EI = Ins.end(); BI != EI;
741 BI++) {
742
743 mOut << "ain_" << (*BI)->getName().str() << ", ";
744 }
Stephen Hines50974742013-02-12 22:11:08 -0800745 }
746
747 if (EF->hasOut() || EF->hasReturn()) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700748 mOut << "aout, ";
Stephen Hines50974742013-02-12 22:11:08 -0800749 }
750
751 if (EF->hasUsrData()) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700752 mOut << Args.back().second << ", ";
Stephen Hines50974742013-02-12 22:11:08 -0800753 }
754
755 // No clipped bounds to pass in.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700756 mOut << "null);\n";
Stephen Hines50974742013-02-12 22:11:08 -0800757
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700758 endFunction();
Stephen Hines50974742013-02-12 22:11:08 -0800759
760 // Add the clipped kernel parameters to the Args list.
761 Args.push_back(std::make_pair("Script.LaunchOptions", "sc"));
762 }
763
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700764 startFunction(AM_Public, false, "void", "forEach_" + EF->getName(), Args);
Stephen Hines593a8942011-05-10 15:29:50 -0700765
Chris Wailesc9454af2014-06-13 17:25:40 -0700766 if (InTypes.size() == 1) {
767 if (InTypes.front() != NULL) {
768 genTypeCheck(InTypes.front(), "ain");
769 }
770
771 } else if (InTypes.size() > 1) {
772 size_t Index = 0;
773 for (RSExportForEach::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
774 BI != EI; BI++, ++Index) {
775
776 if (*BI != NULL) {
777 genTypeCheck(*BI, ("ain_" + Ins[Index]->getName()).str().c_str());
778 }
779 }
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700780 }
Chris Wailesc9454af2014-06-13 17:25:40 -0700781
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700782 if (OET) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700783 genTypeCheck(OET, "aout");
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700784 }
785
Chris Wailesc9454af2014-06-13 17:25:40 -0700786 if (Ins.size() == 1 && (EF->hasOut() || EF->hasReturn())) {
787 mOut.indent() << "Type t0, t1;";
788 genPairwiseDimCheck("ain", "aout");
789
790 } else if (Ins.size() > 1) {
791 mOut.indent() << "Type t0, t1;";
792
793 std::string In0Name = "ain_" + Ins[0]->getName().str();
794
795 for (size_t index = 1; index < Ins.size(); ++index) {
796 genPairwiseDimCheck(In0Name, "ain_" + Ins[index]->getName().str());
797 }
798
799 if (EF->hasOut() || EF->hasReturn()) {
800 genPairwiseDimCheck(In0Name, "aout");
801 }
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700802 }
803
804 std::string FieldPackerName = EF->getName() + "_fp";
805 if (ERT) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700806 if (genCreateFieldPacker(ERT, FieldPackerName.c_str())) {
807 genPackVarOfType(ERT, NULL, FieldPackerName.c_str());
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700808 }
Stephen Hines593a8942011-05-10 15:29:50 -0700809 }
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700810 mOut.indent() << "forEach(" << RS_EXPORT_FOREACH_INDEX_PREFIX
811 << EF->getName();
Stephen Hines593a8942011-05-10 15:29:50 -0700812
Chris Wailesc9454af2014-06-13 17:25:40 -0700813 if (Ins.size() == 1) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700814 mOut << ", ain";
Chris Wailesc9454af2014-06-13 17:25:40 -0700815 } else if (Ins.size() > 1) {
816 mOut << ", new Allocation[]{ain_" << Ins[0]->getName().str();
817
818 for (size_t index = 1; index < Ins.size(); ++index) {
819 mOut << ", ain_" << Ins[index]->getName().str();
820 }
821
822 mOut << "}";
823
824 } else {
825 mOut << ", (Allocation) null";
826 }
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700827
Stephen Hines9ca96e72012-09-13 16:57:06 -0700828 if (EF->hasOut() || EF->hasReturn())
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700829 mOut << ", aout";
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700830 else
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700831 mOut << ", null";
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700832
833 if (EF->hasUsrData())
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700834 mOut << ", " << FieldPackerName;
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700835 else
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700836 mOut << ", null";
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700837
Stephen Hines50974742013-02-12 22:11:08 -0800838 if (mRSContext->getTargetAPI() >= SLANG_JB_MR2_TARGET_API) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700839 mOut << ", sc);\n";
Stephen Hines50974742013-02-12 22:11:08 -0800840 } else {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700841 mOut << ");\n";
Stephen Hines50974742013-02-12 22:11:08 -0800842 }
Stephen Hines593a8942011-05-10 15:29:50 -0700843
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700844 endFunction();
Stephen Hines593a8942011-05-10 15:29:50 -0700845}
846
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700847void RSReflectionJava::genTypeInstanceFromPointer(const RSExportType *ET) {
Stephen Hines48b72bf2011-06-10 15:37:27 -0700848 if (ET->getClass() == RSExportType::ExportClassPointer) {
Stephen Hines9ca96e72012-09-13 16:57:06 -0700849 // For pointer parameters to original forEach kernels.
Stephen Hines48b72bf2011-06-10 15:37:27 -0700850 const RSExportPointerType *EPT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700851 static_cast<const RSExportPointerType *>(ET);
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700852 genTypeInstance(EPT->getPointeeType());
Stephen Hines9ca96e72012-09-13 16:57:06 -0700853 } else {
854 // For handling pass-by-value kernel parameters.
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700855 genTypeInstance(ET);
Stephen Hinesa6b54142012-04-09 18:25:08 -0700856 }
857}
Stephen Hines48b72bf2011-06-10 15:37:27 -0700858
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700859void RSReflectionJava::genTypeInstance(const RSExportType *ET) {
Stephen Hinesa6b54142012-04-09 18:25:08 -0700860 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700861 case RSExportType::ExportClassPrimitive:
862 case RSExportType::ExportClassVector:
863 case RSExportType::ExportClassConstantArray: {
864 std::string TypeName = ET->getElementName();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700865 if (addTypeNameForElement(TypeName)) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700866 mOut.indent() << RS_ELEM_PREFIX << TypeName << " = Element." << TypeName
867 << "(rs);\n";
Stephen Hines48b72bf2011-06-10 15:37:27 -0700868 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700869 break;
870 }
Stephen Hinesa6b54142012-04-09 18:25:08 -0700871
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700872 case RSExportType::ExportClassRecord: {
873 std::string ClassName = ET->getElementName();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700874 if (addTypeNameForElement(ClassName)) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700875 mOut.indent() << RS_ELEM_PREFIX << ClassName << " = " << ClassName
876 << ".createElement(rs);\n";
Stephen Hinesa6b54142012-04-09 18:25:08 -0700877 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700878 break;
879 }
Stephen Hinesa6b54142012-04-09 18:25:08 -0700880
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700881 default:
882 break;
Stephen Hines48b72bf2011-06-10 15:37:27 -0700883 }
884}
885
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700886void RSReflectionJava::genFieldPackerInstance(const RSExportType *ET) {
Stephen Hines1f6c3312012-07-03 17:23:33 -0700887 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700888 case RSExportType::ExportClassPrimitive:
889 case RSExportType::ExportClassVector:
890 case RSExportType::ExportClassConstantArray:
891 case RSExportType::ExportClassRecord: {
892 std::string TypeName = ET->getElementName();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700893 addTypeNameForFieldPacker(TypeName);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700894 break;
895 }
Stephen Hines1f6c3312012-07-03 17:23:33 -0700896
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700897 default:
898 break;
Stephen Hines1f6c3312012-07-03 17:23:33 -0700899 }
900}
901
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700902void RSReflectionJava::genTypeCheck(const RSExportType *ET,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -0700903 const char *VarName) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700904 mOut.indent() << "// check " << VarName << "\n";
Stephen Hines48b72bf2011-06-10 15:37:27 -0700905
906 if (ET->getClass() == RSExportType::ExportClassPointer) {
907 const RSExportPointerType *EPT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700908 static_cast<const RSExportPointerType *>(ET);
Stephen Hines48b72bf2011-06-10 15:37:27 -0700909 ET = EPT->getPointeeType();
910 }
911
912 std::string TypeName;
913
914 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700915 case RSExportType::ExportClassPrimitive:
916 case RSExportType::ExportClassVector:
917 case RSExportType::ExportClassRecord: {
918 TypeName = ET->getElementName();
919 break;
920 }
Stephen Hines48b72bf2011-06-10 15:37:27 -0700921
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700922 default:
923 break;
Stephen Hines48b72bf2011-06-10 15:37:27 -0700924 }
925
926 if (!TypeName.empty()) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700927 mOut.indent() << "if (!" << VarName
928 << ".getType().getElement().isCompatible(" RS_ELEM_PREFIX
929 << TypeName << ")) {\n";
930 mOut.indent() << " throw new RSRuntimeException(\"Type mismatch with "
931 << TypeName << "!\");\n";
932 mOut.indent() << "}\n";
Stephen Hines48b72bf2011-06-10 15:37:27 -0700933 }
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700934}
935
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700936void RSReflectionJava::genPrimitiveTypeExportVariable(const RSExportVar *EV) {
Jean-Luc Brouillet602def72014-05-27 16:11:37 -0700937 slangAssert(
938 (EV->getType()->getClass() == RSExportType::ExportClassPrimitive) &&
939 "Variable should be type of primitive here");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700940
941 const RSExportPrimitiveType *EPT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700942 static_cast<const RSExportPrimitiveType *>(EV->getType());
Stephen Hines0d26cef2012-05-01 19:23:01 -0700943 std::string TypeName = GetTypeName(EPT);
944 std::string VarName = EV->getName();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700945
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700946 genPrivateExportVariable(TypeName, EV->getName());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700947
Stephen Hines5d671782012-01-31 19:32:04 -0800948 if (EV->isConst()) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700949 mOut.indent() << "public final static " << TypeName
950 << " " RS_EXPORT_VAR_CONST_PREFIX << VarName << " = ";
Stephen Hines5d671782012-01-31 19:32:04 -0800951 const clang::APValue &Val = EV->getInit();
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -0700952 genInitValue(Val, EPT->getType() == DataTypeBoolean);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700953 mOut << ";\n";
Stephen Hines5d671782012-01-31 19:32:04 -0800954 } else {
955 // set_*()
Stephen Hines1f6c3312012-07-03 17:23:33 -0700956 // This must remain synchronized, since multiple Dalvik threads may
957 // be calling setters.
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700958 startFunction(AM_PublicSynchronized, false, "void", "set_" + VarName, 1,
959 TypeName.c_str(), "v");
Stephen Hinesbcae1fe2012-09-25 19:17:33 -0700960 if ((EPT->getSize() < 4) || EV->isUnsigned()) {
Stephen Hines1f6c3312012-07-03 17:23:33 -0700961 // We create/cache a per-type FieldPacker. This allows us to reuse the
962 // validation logic (for catching negative inputs from Dalvik, as well
963 // as inputs that are too large to be represented in the unsigned type).
Stephen Hinesbcae1fe2012-09-25 19:17:33 -0700964 // Sub-integer types are also handled specially here, so that we don't
965 // overwrite bytes accidentally.
Stephen Hines1f6c3312012-07-03 17:23:33 -0700966 std::string ElemName = EPT->getElementName();
967 std::string FPName;
968 FPName = RS_FP_PREFIX + ElemName;
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700969 mOut.indent() << "if (" << FPName << "!= null) {\n";
970 mOut.increaseIndent();
971 mOut.indent() << FPName << ".reset();\n";
972 mOut.decreaseIndent();
973 mOut.indent() << "} else {\n";
974 mOut.increaseIndent();
975 mOut.indent() << FPName << " = new FieldPacker(" << EPT->getSize()
976 << ");\n";
977 mOut.decreaseIndent();
978 mOut.indent() << "}\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700979
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700980 genPackVarOfType(EPT, "v", FPName.c_str());
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700981 mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
982 << ", " << FPName << ");\n";
Stephen Hines1f6c3312012-07-03 17:23:33 -0700983 } else {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700984 mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
985 << ", v);\n";
Stephen Hines1f6c3312012-07-03 17:23:33 -0700986 }
987
988 // Dalvik update comes last, since the input may be invalid (and hence
989 // throw an exception).
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700990 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700991
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700992 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700993 }
Shih-wei Liao9e86e192010-06-18 20:42:28 -0700994
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700995 genGetExportVariable(TypeName, VarName);
996 genGetFieldID(VarName);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700997}
998
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -0700999void RSReflectionJava::genInitValue(const clang::APValue &Val, bool asBool) {
1000 switch (Val.getKind()) {
1001 case clang::APValue::Int: {
1002 llvm::APInt api = Val.getInt();
1003 if (asBool) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001004 mOut << ((api.getSExtValue() == 0) ? "false" : "true");
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001005 } else {
1006 // TODO: Handle unsigned correctly
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001007 mOut << api.getSExtValue();
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001008 if (api.getBitWidth() > 32) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001009 mOut << "L";
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001010 }
1011 }
1012 break;
1013 }
1014
1015 case clang::APValue::Float: {
1016 llvm::APFloat apf = Val.getFloat();
1017 llvm::SmallString<30> s;
1018 apf.toString(s);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001019 mOut << s.c_str();
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001020 if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) {
1021 if (s.count('.') == 0) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001022 mOut << ".f";
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001023 } else {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001024 mOut << "f";
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001025 }
1026 }
1027 break;
1028 }
1029
1030 case clang::APValue::ComplexInt:
1031 case clang::APValue::ComplexFloat:
1032 case clang::APValue::LValue:
1033 case clang::APValue::Vector: {
1034 slangAssert(false && "Primitive type cannot have such kind of initializer");
1035 break;
1036 }
1037
1038 default: { slangAssert(false && "Unknown kind of initializer"); }
1039 }
1040}
1041
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001042void RSReflectionJava::genPointerTypeExportVariable(const RSExportVar *EV) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001043 const RSExportType *ET = EV->getType();
1044 const RSExportType *PointeeType;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001045
Stephen Hines6e6578a2011-02-07 18:05:48 -08001046 slangAssert((ET->getClass() == RSExportType::ExportClassPointer) &&
1047 "Variable should be type of pointer here");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001048
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001049 PointeeType = static_cast<const RSExportPointerType *>(ET)->getPointeeType();
Stephen Hines0d26cef2012-05-01 19:23:01 -07001050 std::string TypeName = GetTypeName(ET);
1051 std::string VarName = EV->getName();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001052
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001053 genPrivateExportVariable(TypeName, VarName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001054
Zonr Chang89273bd2010-10-14 20:57:38 +08001055 // bind_*()
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001056 startFunction(AM_Public, false, "void", "bind_" + VarName, 1,
1057 TypeName.c_str(), "v");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001058
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001059 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
1060 mOut.indent() << "if (v == null) bindAllocation(null, "
1061 << RS_EXPORT_VAR_INDEX_PREFIX << VarName << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001062
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001063 if (PointeeType->getClass() == RSExportType::ExportClassRecord) {
1064 mOut.indent() << "else bindAllocation(v.getAllocation(), "
1065 << RS_EXPORT_VAR_INDEX_PREFIX << VarName << ");\n";
1066 } else {
1067 mOut.indent() << "else bindAllocation(v, " << RS_EXPORT_VAR_INDEX_PREFIX
1068 << VarName << ");\n";
1069 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001070
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001071 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001072
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001073 genGetExportVariable(TypeName, VarName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001074}
1075
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001076void RSReflectionJava::genVectorTypeExportVariable(const RSExportVar *EV) {
Stephen Hines6e6578a2011-02-07 18:05:48 -08001077 slangAssert((EV->getType()->getClass() == RSExportType::ExportClassVector) &&
1078 "Variable should be type of vector here");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001079
Stephen Hines0d26cef2012-05-01 19:23:01 -07001080 std::string TypeName = GetTypeName(EV->getType());
1081 std::string VarName = EV->getName();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001082
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001083 genPrivateExportVariable(TypeName, VarName);
1084 genSetExportVariable(TypeName, EV);
1085 genGetExportVariable(TypeName, VarName);
1086 genGetFieldID(VarName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001087}
1088
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001089void RSReflectionJava::genMatrixTypeExportVariable(const RSExportVar *EV) {
Stephen Hines6e6578a2011-02-07 18:05:48 -08001090 slangAssert((EV->getType()->getClass() == RSExportType::ExportClassMatrix) &&
1091 "Variable should be type of matrix here");
Zonr Chang92b344a2010-10-05 20:39:03 +08001092
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001093 const RSExportType *ET = EV->getType();
Stephen Hines0d26cef2012-05-01 19:23:01 -07001094 std::string TypeName = GetTypeName(ET);
1095 std::string VarName = EV->getName();
Zonr Chang92b344a2010-10-05 20:39:03 +08001096
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001097 genPrivateExportVariable(TypeName, VarName);
Zonr Chang92b344a2010-10-05 20:39:03 +08001098
1099 // set_*()
1100 if (!EV->isConst()) {
Stephen Hines0d26cef2012-05-01 19:23:01 -07001101 const char *FieldPackerName = "fp";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001102 startFunction(AM_PublicSynchronized, false, "void", "set_" + VarName, 1,
1103 TypeName.c_str(), "v");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001104 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
Zonr Chang92b344a2010-10-05 20:39:03 +08001105
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001106 if (genCreateFieldPacker(ET, FieldPackerName))
1107 genPackVarOfType(ET, "v", FieldPackerName);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001108 mOut.indent() << "setVar(" RS_EXPORT_VAR_INDEX_PREFIX << VarName << ", "
1109 << FieldPackerName << ");\n";
Zonr Chang92b344a2010-10-05 20:39:03 +08001110
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001111 endFunction();
Zonr Chang92b344a2010-10-05 20:39:03 +08001112 }
1113
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001114 genGetExportVariable(TypeName, VarName);
1115 genGetFieldID(VarName);
Zonr Chang92b344a2010-10-05 20:39:03 +08001116}
1117
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001118void
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001119RSReflectionJava::genConstantArrayTypeExportVariable(const RSExportVar *EV) {
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001120 slangAssert(
1121 (EV->getType()->getClass() == RSExportType::ExportClassConstantArray) &&
1122 "Variable should be type of constant array here");
Zonr Chang2e1dba62010-10-05 22:20:11 +08001123
Stephen Hines0d26cef2012-05-01 19:23:01 -07001124 std::string TypeName = GetTypeName(EV->getType());
1125 std::string VarName = EV->getName();
Zonr Chang2e1dba62010-10-05 22:20:11 +08001126
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001127 genPrivateExportVariable(TypeName, VarName);
1128 genSetExportVariable(TypeName, EV);
1129 genGetExportVariable(TypeName, VarName);
1130 genGetFieldID(VarName);
Zonr Chang2e1dba62010-10-05 22:20:11 +08001131}
1132
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001133void RSReflectionJava::genRecordTypeExportVariable(const RSExportVar *EV) {
Stephen Hines6e6578a2011-02-07 18:05:48 -08001134 slangAssert((EV->getType()->getClass() == RSExportType::ExportClassRecord) &&
1135 "Variable should be type of struct here");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001136
Stephen Hines0d26cef2012-05-01 19:23:01 -07001137 std::string TypeName = GetTypeName(EV->getType());
1138 std::string VarName = EV->getName();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001139
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001140 genPrivateExportVariable(TypeName, VarName);
1141 genSetExportVariable(TypeName, EV);
1142 genGetExportVariable(TypeName, VarName);
1143 genGetFieldID(VarName);
Stephen Hines0d26cef2012-05-01 19:23:01 -07001144}
1145
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001146void RSReflectionJava::genPrivateExportVariable(const std::string &TypeName,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001147 const std::string &VarName) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001148 mOut.indent() << "private " << TypeName << " " << RS_EXPORT_VAR_PREFIX
1149 << VarName << ";\n";
Stephen Hines0d26cef2012-05-01 19:23:01 -07001150}
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001151
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001152void RSReflectionJava::genSetExportVariable(const std::string &TypeName,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001153 const RSExportVar *EV) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001154 if (!EV->isConst()) {
Stephen Hines0d26cef2012-05-01 19:23:01 -07001155 const char *FieldPackerName = "fp";
1156 std::string VarName = EV->getName();
1157 const RSExportType *ET = EV->getType();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001158 startFunction(AM_PublicSynchronized, false, "void", "set_" + VarName, 1,
1159 TypeName.c_str(), "v");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001160 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001161
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001162 if (genCreateFieldPacker(ET, FieldPackerName))
1163 genPackVarOfType(ET, "v", FieldPackerName);
Stephen Hinesa6b54142012-04-09 18:25:08 -07001164
1165 if (mRSContext->getTargetAPI() < SLANG_JB_TARGET_API) {
1166 // Legacy apps must use the old setVar() without Element/dim components.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001167 mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
1168 << ", " << FieldPackerName << ");\n";
Stephen Hinesa6b54142012-04-09 18:25:08 -07001169 } else {
1170 // We only have support for one-dimensional array reflection today,
1171 // but the entry point (i.e. setVar()) takes an array of dimensions.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001172 mOut.indent() << "int []__dimArr = new int[1];\n";
1173 mOut.indent() << "__dimArr[0] = " << ET->getSize() << ";\n";
1174 mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
1175 << ", " << FieldPackerName << ", " << RS_ELEM_PREFIX
1176 << ET->getElementName() << ", __dimArr);\n";
Stephen Hinesa6b54142012-04-09 18:25:08 -07001177 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001178
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001179 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001180 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001181}
1182
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001183void RSReflectionJava::genGetExportVariable(const std::string &TypeName,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001184 const std::string &VarName) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001185 startFunction(AM_Public, false, TypeName.c_str(), "get_" + VarName, 0);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001186
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001187 mOut.indent() << "return " << RS_EXPORT_VAR_PREFIX << VarName << ";\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001188
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001189 endFunction();
Stephen Hines28d60bc2012-10-15 15:54:16 -07001190}
1191
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001192void RSReflectionJava::genGetFieldID(const std::string &VarName) {
Stephen Hines28d60bc2012-10-15 15:54:16 -07001193 // We only generate getFieldID_*() for non-Pointer (bind) types.
Tim Murrayb81a9932012-10-10 15:56:02 -07001194 if (mRSContext->getTargetAPI() >= SLANG_JB_MR1_TARGET_API) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001195 startFunction(AM_Public, false, "Script.FieldID", "getFieldID_" + VarName,
1196 0);
Tim Murrayb81a9932012-10-10 15:56:02 -07001197
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001198 mOut.indent() << "return createFieldID(" << RS_EXPORT_VAR_INDEX_PREFIX
1199 << VarName << ", null);\n";
Tim Murrayb81a9932012-10-10 15:56:02 -07001200
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001201 endFunction();
Tim Murrayb81a9932012-10-10 15:56:02 -07001202 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001203}
1204
1205/******************* Methods to generate script class /end *******************/
1206
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001207bool RSReflectionJava::genCreateFieldPacker(const RSExportType *ET,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001208 const char *FieldPackerName) {
Jean-Luc Brouilletc95381a2014-05-14 21:24:45 -07001209 size_t AllocSize = ET->getAllocSize();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001210 if (AllocSize > 0)
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001211 mOut.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker("
1212 << AllocSize << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001213 else
1214 return false;
1215 return true;
1216}
1217
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001218void RSReflectionJava::genPackVarOfType(const RSExportType *ET,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001219 const char *VarName,
1220 const char *FieldPackerName) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001221 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001222 case RSExportType::ExportClassPrimitive:
1223 case RSExportType::ExportClassVector: {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001224 mOut.indent() << FieldPackerName << "."
1225 << GetPackerAPIName(
1226 static_cast<const RSExportPrimitiveType *>(ET)) << "("
1227 << VarName << ");\n";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001228 break;
1229 }
1230 case RSExportType::ExportClassPointer: {
1231 // Must reflect as type Allocation in Java
1232 const RSExportType *PointeeType =
1233 static_cast<const RSExportPointerType *>(ET)->getPointeeType();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001234
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001235 if (PointeeType->getClass() != RSExportType::ExportClassRecord) {
1236 mOut.indent() << FieldPackerName << ".addI32(" << VarName
1237 << ".getPtr());\n";
1238 } else {
1239 mOut.indent() << FieldPackerName << ".addI32(" << VarName
1240 << ".getAllocation().getPtr());\n";
1241 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001242 break;
1243 }
1244 case RSExportType::ExportClassMatrix: {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001245 mOut.indent() << FieldPackerName << ".addMatrix(" << VarName << ");\n";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001246 break;
1247 }
1248 case RSExportType::ExportClassConstantArray: {
1249 const RSExportConstantArrayType *ECAT =
1250 static_cast<const RSExportConstantArrayType *>(ET);
1251
1252 // TODO(zonr): more elegant way. Currently, we obtain the unique index
1253 // variable (this method involves recursive call which means
1254 // we may have more than one level loop, therefore we can't
1255 // always use the same index variable name here) name given
1256 // in the for-loop from counting the '.' in @VarName.
1257 unsigned Level = 0;
1258 size_t LastDotPos = 0;
1259 std::string ElementVarName(VarName);
1260
1261 while (LastDotPos != std::string::npos) {
1262 LastDotPos = ElementVarName.find_first_of('.', LastDotPos + 1);
1263 Level++;
1264 }
1265 std::string IndexVarName("ct");
1266 IndexVarName.append(llvm::utostr_32(Level));
1267
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001268 mOut.indent() << "for (int " << IndexVarName << " = 0; " << IndexVarName
1269 << " < " << ECAT->getSize() << "; " << IndexVarName << "++)";
1270 mOut.startBlock();
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001271
1272 ElementVarName.append("[" + IndexVarName + "]");
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001273 genPackVarOfType(ECAT->getElementType(), ElementVarName.c_str(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001274 FieldPackerName);
1275
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001276 mOut.endBlock();
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001277 break;
1278 }
1279 case RSExportType::ExportClassRecord: {
1280 const RSExportRecordType *ERT = static_cast<const RSExportRecordType *>(ET);
1281 // Relative pos from now on in field packer
1282 unsigned Pos = 0;
1283
1284 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
1285 E = ERT->fields_end();
1286 I != E; I++) {
1287 const RSExportRecordType::Field *F = *I;
1288 std::string FieldName;
1289 size_t FieldOffset = F->getOffsetInParent();
1290 const RSExportType *T = F->getType();
1291 size_t FieldStoreSize = T->getStoreSize();
1292 size_t FieldAllocSize = T->getAllocSize();
1293
1294 if (VarName != NULL)
1295 FieldName = VarName + ("." + F->getName());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001296 else
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001297 FieldName = F->getName();
Zonr Chang89273bd2010-10-14 20:57:38 +08001298
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001299 if (FieldOffset > Pos) {
1300 mOut.indent() << FieldPackerName << ".skip(" << (FieldOffset - Pos)
1301 << ");\n";
1302 }
Zonr Chang89273bd2010-10-14 20:57:38 +08001303
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001304 genPackVarOfType(F->getType(), FieldName.c_str(), FieldPackerName);
Zonr Chang89273bd2010-10-14 20:57:38 +08001305
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001306 // There is padding in the field type
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001307 if (FieldAllocSize > FieldStoreSize) {
1308 mOut.indent() << FieldPackerName << ".skip("
1309 << (FieldAllocSize - FieldStoreSize) << ");\n";
1310 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001311
1312 Pos = FieldOffset + FieldAllocSize;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001313 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001314
1315 // There maybe some padding after the struct
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001316 if (ERT->getAllocSize() > Pos) {
1317 mOut.indent() << FieldPackerName << ".skip(" << ERT->getAllocSize() - Pos
1318 << ");\n";
1319 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001320 break;
1321 }
1322 default: { slangAssert(false && "Unknown class of type"); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001323 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001324}
1325
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001326void RSReflectionJava::genAllocateVarOfType(const RSExportType *T,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001327 const std::string &VarName) {
Zonr Chang2e1dba62010-10-05 22:20:11 +08001328 switch (T->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001329 case RSExportType::ExportClassPrimitive: {
1330 // Primitive type like int in Java has its own storage once it's declared.
1331 //
1332 // FIXME: Should we allocate storage for RS object?
1333 // if (static_cast<const RSExportPrimitiveType *>(T)->isRSObjectType())
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001334 // mOut.indent() << VarName << " = new " << GetTypeName(T) << "();\n";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001335 break;
1336 }
1337 case RSExportType::ExportClassPointer: {
1338 // Pointer type is an instance of Allocation or a TypeClass whose value is
1339 // expected to be assigned by programmer later in Java program. Therefore
1340 // we don't reflect things like [VarName] = new Allocation();
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001341 mOut.indent() << VarName << " = null;\n";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001342 break;
1343 }
1344 case RSExportType::ExportClassConstantArray: {
1345 const RSExportConstantArrayType *ECAT =
1346 static_cast<const RSExportConstantArrayType *>(T);
1347 const RSExportType *ElementType = ECAT->getElementType();
Zonr Chang2e1dba62010-10-05 22:20:11 +08001348
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001349 mOut.indent() << VarName << " = new " << GetTypeName(ElementType) << "["
1350 << ECAT->getSize() << "];\n";
Zonr Chang2f1451c2010-10-14 02:58:28 +08001351
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001352 // Primitive type element doesn't need allocation code.
1353 if (ElementType->getClass() != RSExportType::ExportClassPrimitive) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001354 mOut.indent() << "for (int $ct = 0; $ct < " << ECAT->getSize()
1355 << "; $ct++)";
1356 mOut.startBlock();
Zonr Chang2e1dba62010-10-05 22:20:11 +08001357
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001358 std::string ElementVarName(VarName);
1359 ElementVarName.append("[$ct]");
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001360 genAllocateVarOfType(ElementType, ElementVarName);
Zonr Chang2e1dba62010-10-05 22:20:11 +08001361
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001362 mOut.endBlock();
Zonr Chang2e1dba62010-10-05 22:20:11 +08001363 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001364 break;
1365 }
1366 case RSExportType::ExportClassVector:
1367 case RSExportType::ExportClassMatrix:
1368 case RSExportType::ExportClassRecord: {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001369 mOut.indent() << VarName << " = new " << GetTypeName(T) << "();\n";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001370 break;
1371 }
Zonr Chang2e1dba62010-10-05 22:20:11 +08001372 }
Zonr Chang2e1dba62010-10-05 22:20:11 +08001373}
1374
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001375void RSReflectionJava::genNewItemBufferIfNull(const char *Index) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001376 mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME " == null) ";
1377 mOut << RS_TYPE_ITEM_BUFFER_NAME << " = new " << RS_TYPE_ITEM_CLASS_NAME
1378 << "[getType().getX() /* count */];\n";
1379 if (Index != NULL) {
1380 mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME << "[" << Index
1381 << "] == null) ";
1382 mOut << RS_TYPE_ITEM_BUFFER_NAME << "[" << Index << "] = new "
1383 << RS_TYPE_ITEM_CLASS_NAME << "();\n";
1384 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001385}
1386
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001387void RSReflectionJava::genNewItemBufferPackerIfNull() {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001388 mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " == null) ";
1389 mOut << RS_TYPE_ITEM_BUFFER_PACKER_NAME " = new FieldPacker("
Tim Murray3a38b742014-07-02 10:41:08 -07001390 << mItemSizeof << " * getType().getX()/* count */);\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001391}
1392
1393/********************** Methods to generate type class **********************/
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001394bool RSReflectionJava::genTypeClass(const RSExportRecordType *ERT,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001395 std::string &ErrorMsg) {
Stephen Hinesa6b54142012-04-09 18:25:08 -07001396 std::string ClassName = ERT->getElementName();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001397 std::string superClassName = getRSPackageName();
Tim Murrayf69e1e52013-01-17 13:57:24 -08001398 superClassName += RS_TYPE_CLASS_SUPER_CLASS_NAME;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001399
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001400 if (!startClass(AM_Public, false, ClassName, superClassName.c_str(),
1401 ErrorMsg))
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001402 return false;
1403
Stephen Hines4cc67fc2011-01-31 16:48:57 -08001404 mGeneratedFileNames->push_back(ClassName);
1405
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001406 genTypeItemClass(ERT);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001407
1408 // Declare item buffer and item buffer packer
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001409 mOut.indent() << "private " << RS_TYPE_ITEM_CLASS_NAME << " "
1410 << RS_TYPE_ITEM_BUFFER_NAME << "[];\n";
1411 mOut.indent() << "private FieldPacker " << RS_TYPE_ITEM_BUFFER_PACKER_NAME
1412 << ";\n";
1413 mOut.indent() << "private static java.lang.ref.WeakReference<Element> "
1414 << RS_TYPE_ELEMENT_REF_NAME
1415 << " = new java.lang.ref.WeakReference<Element>(null);\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001416
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001417 genTypeClassConstructor(ERT);
1418 genTypeClassCopyToArrayLocal(ERT);
1419 genTypeClassCopyToArray(ERT);
1420 genTypeClassItemSetter(ERT);
1421 genTypeClassItemGetter(ERT);
1422 genTypeClassComponentSetter(ERT);
1423 genTypeClassComponentGetter(ERT);
1424 genTypeClassCopyAll(ERT);
Stephen Hines82754d82013-01-18 19:46:06 -08001425 if (!mRSContext->isCompatLib()) {
1426 // Skip the resize method if we are targeting a compatibility library.
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001427 genTypeClassResize();
Stephen Hines82754d82013-01-18 19:46:06 -08001428 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001429
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001430 endClass();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001431
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001432 resetFieldIndex();
1433 clearFieldIndexMap();
Zonr Chang66aa2992010-10-05 15:56:31 +08001434
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001435 return true;
1436}
1437
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001438void RSReflectionJava::genTypeItemClass(const RSExportRecordType *ERT) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001439 mOut.indent() << "static public class " RS_TYPE_ITEM_CLASS_NAME;
1440 mOut.startBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001441
Tim Murray3a38b742014-07-02 10:41:08 -07001442 // Sizeof should not be exposed for 64-bit; it is not accurate
1443 if (mRSContext->getTargetAPI() < 21) {
1444 mOut.indent() << "public static final int sizeof = " << ERT->getAllocSize()
1445 << ";\n";
1446 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001447
1448 // Member elements
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001449 mOut << "\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001450 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001451 FE = ERT->fields_end();
1452 FI != FE; FI++) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001453 mOut.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName()
1454 << ";\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001455 }
1456
1457 // Constructor
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001458 mOut << "\n";
1459 mOut.indent() << RS_TYPE_ITEM_CLASS_NAME << "()";
1460 mOut.startBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001461
1462 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001463 FE = ERT->fields_end();
1464 FI != FE; FI++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001465 const RSExportRecordType::Field *F = *FI;
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001466 genAllocateVarOfType(F->getType(), F->getName());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001467 }
1468
1469 // end Constructor
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001470 mOut.endBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001471
1472 // end Item class
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001473 mOut.endBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001474}
1475
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001476void RSReflectionJava::genTypeClassConstructor(const RSExportRecordType *ERT) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001477 const char *RenderScriptVar = "rs";
1478
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001479 startFunction(AM_Public, true, "Element", "createElement", 1, "RenderScript",
1480 RenderScriptVar);
Jason Sams381e95f2011-11-30 14:01:43 -08001481
Stephen Hinese67239d2012-02-24 15:08:36 -08001482 // TODO(all): Fix weak-refs + multi-context issue.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001483 // mOut.indent() << "Element e = " << RS_TYPE_ELEMENT_REF_NAME
Jean-Luc Brouillet29689212014-05-27 13:25:31 -07001484 // << ".get();\n";
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001485 // mOut.indent() << "if (e != null) return e;\n";
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001486 RSReflectionJavaElementBuilder builder("eb", ERT, RenderScriptVar, &mOut,
1487 mRSContext, this);
1488 builder.generate();
1489
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001490 mOut.indent() << "return eb.create();\n";
1491 // mOut.indent() << "e = eb.create();\n";
1492 // mOut.indent() << RS_TYPE_ELEMENT_REF_NAME
Jean-Luc Brouillet29689212014-05-27 13:25:31 -07001493 // << " = new java.lang.ref.WeakReference<Element>(e);\n";
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001494 // mOut.indent() << "return e;\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001495 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001496
Jason Sams381e95f2011-11-30 14:01:43 -08001497 // private with element
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001498 startFunction(AM_Private, false, NULL, getClassName(), 1, "RenderScript",
1499 RenderScriptVar);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001500 mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
1501 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
1502 mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001503 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001504
1505 // 1D without usage
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001506 startFunction(AM_Public, false, NULL, getClassName(), 2, "RenderScript",
1507 RenderScriptVar, "int", "count");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001508
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001509 mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
1510 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
1511 mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001512 // Call init() in super class
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001513 mOut.indent() << "init(" << RenderScriptVar << ", count);\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001514 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001515
Jason Sams381e95f2011-11-30 14:01:43 -08001516 // 1D with usage
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001517 startFunction(AM_Public, false, NULL, getClassName(), 3, "RenderScript",
1518 RenderScriptVar, "int", "count", "int", "usages");
Jason Sams91fe83b2010-12-06 17:07:12 -08001519
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001520 mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
1521 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
1522 mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
Jason Sams91fe83b2010-12-06 17:07:12 -08001523 // Call init() in super class
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001524 mOut.indent() << "init(" << RenderScriptVar << ", count, usages);\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001525 endFunction();
Jason Sams91fe83b2010-12-06 17:07:12 -08001526
Jason Sams381e95f2011-11-30 14:01:43 -08001527 // create1D with usage
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001528 startFunction(AM_Public, true, getClassName().c_str(), "create1D", 3,
1529 "RenderScript", RenderScriptVar, "int", "dimX", "int",
1530 "usages");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001531 mOut.indent() << getClassName() << " obj = new " << getClassName() << "("
1532 << RenderScriptVar << ");\n";
1533 mOut.indent() << "obj.mAllocation = Allocation.createSized("
1534 "rs, obj.mElement, dimX, usages);\n";
1535 mOut.indent() << "return obj;\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001536 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001537
1538 // create1D without usage
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001539 startFunction(AM_Public, true, getClassName().c_str(), "create1D", 2,
1540 "RenderScript", RenderScriptVar, "int", "dimX");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001541 mOut.indent() << "return create1D(" << RenderScriptVar
1542 << ", dimX, Allocation.USAGE_SCRIPT);\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001543 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001544
Jason Sams381e95f2011-11-30 14:01:43 -08001545 // create2D without usage
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001546 startFunction(AM_Public, true, getClassName().c_str(), "create2D", 3,
1547 "RenderScript", RenderScriptVar, "int", "dimX", "int", "dimY");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001548 mOut.indent() << "return create2D(" << RenderScriptVar
1549 << ", dimX, dimY, Allocation.USAGE_SCRIPT);\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001550 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001551
1552 // create2D with usage
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001553 startFunction(AM_Public, true, getClassName().c_str(), "create2D", 4,
1554 "RenderScript", RenderScriptVar, "int", "dimX", "int", "dimY",
1555 "int", "usages");
Jason Sams381e95f2011-11-30 14:01:43 -08001556
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001557 mOut.indent() << getClassName() << " obj = new " << getClassName() << "("
1558 << RenderScriptVar << ");\n";
1559 mOut.indent() << "Type.Builder b = new Type.Builder(rs, obj.mElement);\n";
1560 mOut.indent() << "b.setX(dimX);\n";
1561 mOut.indent() << "b.setY(dimY);\n";
1562 mOut.indent() << "Type t = b.create();\n";
1563 mOut.indent() << "obj.mAllocation = Allocation.createTyped(rs, t, usages);\n";
1564 mOut.indent() << "return obj;\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001565 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001566
Jason Sams381e95f2011-11-30 14:01:43 -08001567 // createTypeBuilder
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001568 startFunction(AM_Public, true, "Type.Builder", "createTypeBuilder", 1,
1569 "RenderScript", RenderScriptVar);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001570 mOut.indent() << "Element e = createElement(" << RenderScriptVar << ");\n";
1571 mOut.indent() << "return new Type.Builder(rs, e);\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001572 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001573
1574 // createCustom with usage
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001575 startFunction(AM_Public, true, getClassName().c_str(), "createCustom", 3,
1576 "RenderScript", RenderScriptVar, "Type.Builder", "tb", "int",
1577 "usages");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001578 mOut.indent() << getClassName() << " obj = new " << getClassName() << "("
1579 << RenderScriptVar << ");\n";
1580 mOut.indent() << "Type t = tb.create();\n";
1581 mOut.indent() << "if (t.getElement() != obj.mElement) {\n";
1582 mOut.indent() << " throw new RSIllegalArgumentException("
1583 "\"Type.Builder did not match expected element type.\");\n";
1584 mOut.indent() << "}\n";
1585 mOut.indent() << "obj.mAllocation = Allocation.createTyped(rs, t, usages);\n";
1586 mOut.indent() << "return obj;\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001587 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001588}
1589
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001590void RSReflectionJava::genTypeClassCopyToArray(const RSExportRecordType *ERT) {
1591 startFunction(AM_Private, false, "void", "copyToArray", 2,
1592 RS_TYPE_ITEM_CLASS_NAME, "i", "int", "index");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001593
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001594 genNewItemBufferPackerIfNull();
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001595 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << ".reset(index * "
Tim Murray3a38b742014-07-02 10:41:08 -07001596 << mItemSizeof << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001597
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001598 mOut.indent() << "copyToArrayLocal(i, " RS_TYPE_ITEM_BUFFER_PACKER_NAME
1599 ");\n";
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001600
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001601 endFunction();
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001602}
1603
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001604void
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001605RSReflectionJava::genTypeClassCopyToArrayLocal(const RSExportRecordType *ERT) {
1606 startFunction(AM_Private, false, "void", "copyToArrayLocal", 2,
1607 RS_TYPE_ITEM_CLASS_NAME, "i", "FieldPacker", "fp");
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001608
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001609 genPackVarOfType(ERT, "i", "fp");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001610
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001611 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001612}
1613
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001614void RSReflectionJava::genTypeClassItemSetter(const RSExportRecordType *ERT) {
1615 startFunction(AM_PublicSynchronized, false, "void", "set", 3,
1616 RS_TYPE_ITEM_CLASS_NAME, "i", "int", "index", "boolean",
1617 "copyNow");
1618 genNewItemBufferIfNull(NULL);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001619 mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << "[index] = i;\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001620
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001621 mOut.indent() << "if (copyNow) ";
1622 mOut.startBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001623
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001624 mOut.indent() << "copyToArray(i, index);\n";
Tim Murray3a38b742014-07-02 10:41:08 -07001625 mOut.indent() << "FieldPacker fp = new FieldPacker(" << mItemSizeof << ");\n";
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001626 mOut.indent() << "copyToArrayLocal(i, fp);\n";
1627 mOut.indent() << "mAllocation.setFromFieldPacker(index, fp);\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001628
1629 // End of if (copyNow)
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001630 mOut.endBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001631
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001632 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001633}
1634
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001635void RSReflectionJava::genTypeClassItemGetter(const RSExportRecordType *ERT) {
1636 startFunction(AM_PublicSynchronized, false, RS_TYPE_ITEM_CLASS_NAME, "get", 1,
1637 "int", "index");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001638 mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME
1639 << " == null) return null;\n";
1640 mOut.indent() << "return " << RS_TYPE_ITEM_BUFFER_NAME << "[index];\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001641 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001642}
1643
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001644void
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001645RSReflectionJava::genTypeClassComponentSetter(const RSExportRecordType *ERT) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001646 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001647 FE = ERT->fields_end();
1648 FI != FE; FI++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001649 const RSExportRecordType::Field *F = *FI;
1650 size_t FieldOffset = F->getOffsetInParent();
Jean-Luc Brouilletc95381a2014-05-14 21:24:45 -07001651 size_t FieldStoreSize = F->getType()->getStoreSize();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001652 unsigned FieldIndex = getFieldIndex(F);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001653
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001654 startFunction(AM_PublicSynchronized, false, "void", "set_" + F->getName(),
1655 3, "int", "index", GetTypeName(F->getType()).c_str(), "v",
1656 "boolean", "copyNow");
1657 genNewItemBufferPackerIfNull();
1658 genNewItemBufferIfNull("index");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001659 mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << "[index]." << F->getName()
1660 << " = v;\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001661
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001662 mOut.indent() << "if (copyNow) ";
1663 mOut.startBlock();
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -07001664
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001665 if (FieldOffset > 0) {
1666 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << ".reset(index * "
Tim Murray3a38b742014-07-02 10:41:08 -07001667 << mItemSizeof << " + " << FieldOffset
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001668 << ");\n";
1669 } else {
1670 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << ".reset(index * "
Tim Murray3a38b742014-07-02 10:41:08 -07001671 << mItemSizeof << ");\n";
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001672 }
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001673 genPackVarOfType(F->getType(), "v", RS_TYPE_ITEM_BUFFER_PACKER_NAME);
1674
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001675 mOut.indent() << "FieldPacker fp = new FieldPacker(" << FieldStoreSize
1676 << ");\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001677 genPackVarOfType(F->getType(), "v", "fp");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001678 mOut.indent() << "mAllocation.setFromFieldPacker(index, " << FieldIndex
1679 << ", fp);\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001680
1681 // End of if (copyNow)
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001682 mOut.endBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001683
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001684 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001685 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001686}
1687
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001688void
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001689RSReflectionJava::genTypeClassComponentGetter(const RSExportRecordType *ERT) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001690 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001691 FE = ERT->fields_end();
1692 FI != FE; FI++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001693 const RSExportRecordType::Field *F = *FI;
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001694 startFunction(AM_PublicSynchronized, false,
1695 GetTypeName(F->getType()).c_str(), "get_" + F->getName(), 1,
1696 "int", "index");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001697 mOut.indent() << "if (" RS_TYPE_ITEM_BUFFER_NAME << " == null) return "
1698 << GetTypeNullValue(F->getType()) << ";\n";
1699 mOut.indent() << "return " RS_TYPE_ITEM_BUFFER_NAME << "[index]."
1700 << F->getName() << ";\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001701 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001702 }
Shih-wei Liao9c631ff2010-09-17 11:57:29 -07001703}
1704
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001705void RSReflectionJava::genTypeClassCopyAll(const RSExportRecordType *ERT) {
1706 startFunction(AM_PublicSynchronized, false, "void", "copyAll", 0);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001707
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001708 mOut.indent() << "for (int ct = 0; ct < " << RS_TYPE_ITEM_BUFFER_NAME
1709 << ".length; ct++)"
1710 << " copyToArray(" << RS_TYPE_ITEM_BUFFER_NAME
1711 << "[ct], ct);\n";
1712 mOut.indent() << "mAllocation.setFromFieldPacker(0, "
1713 << RS_TYPE_ITEM_BUFFER_PACKER_NAME ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001714
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001715 endFunction();
Shih-wei Liao9c631ff2010-09-17 11:57:29 -07001716}
1717
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001718void RSReflectionJava::genTypeClassResize() {
1719 startFunction(AM_PublicSynchronized, false, "void", "resize", 1, "int",
1720 "newSize");
Zonr Changd42a4292010-10-17 02:38:43 +08001721
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001722 mOut.indent() << "if (mItemArray != null) ";
1723 mOut.startBlock();
1724 mOut.indent() << "int oldSize = mItemArray.length;\n";
1725 mOut.indent() << "int copySize = Math.min(oldSize, newSize);\n";
1726 mOut.indent() << "if (newSize == oldSize) return;\n";
1727 mOut.indent() << "Item ni[] = new Item[newSize];\n";
1728 mOut.indent() << "System.arraycopy(mItemArray, 0, ni, 0, copySize);\n";
1729 mOut.indent() << "mItemArray = ni;\n";
1730 mOut.endBlock();
1731 mOut.indent() << "mAllocation.resize(newSize);\n";
Zonr Changd42a4292010-10-17 02:38:43 +08001732
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001733 mOut.indent() << "if (" RS_TYPE_ITEM_BUFFER_PACKER_NAME
1734 " != null) " RS_TYPE_ITEM_BUFFER_PACKER_NAME " = "
Tim Murray3a38b742014-07-02 10:41:08 -07001735 "new FieldPacker(" << mItemSizeof << " * getType().getX()/* count */);\n";
Jason Samscedffd92010-12-16 15:29:49 -08001736
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001737 endFunction();
Zonr Changd42a4292010-10-17 02:38:43 +08001738}
1739
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001740/******************** Methods to generate type class /end ********************/
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001741
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001742/********** Methods to create Element in Java of given record type ***********/
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001743
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001744RSReflectionJavaElementBuilder::RSReflectionJavaElementBuilder(
1745 const char *ElementBuilderName, const RSExportRecordType *ERT,
1746 const char *RenderScriptVar, GeneratedFile *Out, const RSContext *RSContext,
1747 RSReflectionJava *Reflection)
1748 : mElementBuilderName(ElementBuilderName), mERT(ERT),
1749 mRenderScriptVar(RenderScriptVar), mOut(Out), mPaddingFieldIndex(1),
1750 mRSContext(RSContext), mReflection(Reflection) {
1751 if (mRSContext->getTargetAPI() < SLANG_ICS_TARGET_API) {
1752 mPaddingPrefix = "#padding_";
1753 } else {
1754 mPaddingPrefix = "#rs_padding_";
1755 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001756}
1757
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001758void RSReflectionJavaElementBuilder::generate() {
1759 mOut->indent() << "Element.Builder " << mElementBuilderName
1760 << " = new Element.Builder(" << mRenderScriptVar << ");\n";
1761 genAddElement(mERT, "", /* ArraySize = */ 0);
1762}
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001763
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001764void RSReflectionJavaElementBuilder::genAddElement(const RSExportType *ET,
1765 const std::string &VarName,
1766 unsigned ArraySize) {
Stephen Hines47aca4e2012-03-08 20:07:28 -08001767 std::string ElementConstruct = GetBuiltinElementConstruct(ET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001768
Stephen Hines47aca4e2012-03-08 20:07:28 -08001769 if (ElementConstruct != "") {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001770 genAddStatementStart();
1771 *mOut << ElementConstruct << "(" << mRenderScriptVar << ")";
1772 genAddStatementEnd(VarName, ArraySize);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001773 } else {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001774
1775 switch (ET->getClass()) {
1776 case RSExportType::ExportClassPrimitive: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001777 const RSExportPrimitiveType *EPT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001778 static_cast<const RSExportPrimitiveType *>(ET);
Stephen Hines47aca4e2012-03-08 20:07:28 -08001779 const char *DataTypeName =
1780 RSExportPrimitiveType::getRSReflectionType(EPT)->rs_type;
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001781 genAddStatementStart();
1782 *mOut << "Element.createUser(" << mRenderScriptVar
1783 << ", Element.DataType." << DataTypeName << ")";
1784 genAddStatementEnd(VarName, ArraySize);
1785 break;
1786 }
1787 case RSExportType::ExportClassVector: {
1788 const RSExportVectorType *EVT =
1789 static_cast<const RSExportVectorType *>(ET);
1790 const char *DataTypeName =
1791 RSExportPrimitiveType::getRSReflectionType(EVT)->rs_type;
1792 genAddStatementStart();
1793 *mOut << "Element.createVector(" << mRenderScriptVar
1794 << ", Element.DataType." << DataTypeName << ", "
1795 << EVT->getNumElement() << ")";
1796 genAddStatementEnd(VarName, ArraySize);
1797 break;
1798 }
1799 case RSExportType::ExportClassPointer:
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001800 // Pointer type variable should be resolved in
1801 // GetBuiltinElementConstruct()
Stephen Hines6e6578a2011-02-07 18:05:48 -08001802 slangAssert(false && "??");
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001803 break;
1804 case RSExportType::ExportClassMatrix:
Zonr Chang92b344a2010-10-05 20:39:03 +08001805 // Matrix type variable should be resolved
1806 // in GetBuiltinElementConstruct()
Stephen Hines6e6578a2011-02-07 18:05:48 -08001807 slangAssert(false && "??");
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001808 break;
1809 case RSExportType::ExportClassConstantArray: {
Zonr Chang2e1dba62010-10-05 22:20:11 +08001810 const RSExportConstantArrayType *ECAT =
1811 static_cast<const RSExportConstantArrayType *>(ET);
Zonr Chang2e1dba62010-10-05 22:20:11 +08001812
Zonr Chang89273bd2010-10-14 20:57:38 +08001813 const RSExportType *ElementType = ECAT->getElementType();
1814 if (ElementType->getClass() != RSExportType::ExportClassRecord) {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001815 genAddElement(ECAT->getElementType(), VarName, ECAT->getSize());
Zonr Chang89273bd2010-10-14 20:57:38 +08001816 } else {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001817 std::string NewElementBuilderName(mElementBuilderName);
Zonr Chang89273bd2010-10-14 20:57:38 +08001818 NewElementBuilderName.append(1, '_');
Zonr Chang2e1dba62010-10-05 22:20:11 +08001819
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001820 RSReflectionJavaElementBuilder builder(
1821 NewElementBuilderName.c_str(),
1822 static_cast<const RSExportRecordType *>(ElementType),
1823 mRenderScriptVar, mOut, mRSContext, mReflection);
1824 builder.generate();
1825
Zonr Chang89273bd2010-10-14 20:57:38 +08001826 ArraySize = ECAT->getSize();
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001827 genAddStatementStart();
1828 *mOut << NewElementBuilderName << ".create()";
1829 genAddStatementEnd(VarName, ArraySize);
Zonr Chang89273bd2010-10-14 20:57:38 +08001830 }
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001831 break;
1832 }
1833 case RSExportType::ExportClassRecord: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001834 // Simalar to case of RSExportType::ExportClassRecord in genPackVarOfType.
1835 //
zonr6315f762010-10-05 15:35:14 +08001836 // TODO(zonr): Generalize these two function such that there's no
1837 // duplicated codes.
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001838 const RSExportRecordType *ERT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001839 static_cast<const RSExportRecordType *>(ET);
1840 int Pos = 0; // relative pos from now on
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001841
1842 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001843 E = ERT->fields_end();
1844 I != E; I++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001845 const RSExportRecordType::Field *F = *I;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001846 int FieldOffset = F->getOffsetInParent();
Jean-Luc Brouilletc95381a2014-05-14 21:24:45 -07001847 const RSExportType *T = F->getType();
1848 int FieldStoreSize = T->getStoreSize();
1849 int FieldAllocSize = T->getAllocSize();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001850
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001851 std::string FieldName;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001852 if (!VarName.empty())
1853 FieldName = VarName + "." + F->getName();
1854 else
1855 FieldName = F->getName();
1856
1857 // Alignment
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001858 genAddPadding(FieldOffset - Pos);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001859
1860 // eb.add(...)
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001861 mReflection->addFieldIndexMapping(F);
Zonr Chang89273bd2010-10-14 20:57:38 +08001862 if (F->getType()->getClass() != RSExportType::ExportClassRecord) {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001863 genAddElement(F->getType(), FieldName, 0);
Zonr Chang89273bd2010-10-14 20:57:38 +08001864 } else {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001865 std::string NewElementBuilderName(mElementBuilderName);
Zonr Chang89273bd2010-10-14 20:57:38 +08001866 NewElementBuilderName.append(1, '_');
1867
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001868 RSReflectionJavaElementBuilder builder(
1869 NewElementBuilderName.c_str(),
1870 static_cast<const RSExportRecordType *>(F->getType()),
1871 mRenderScriptVar, mOut, mRSContext, mReflection);
1872 builder.generate();
Zonr Chang89273bd2010-10-14 20:57:38 +08001873
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001874 genAddStatementStart();
1875 *mOut << NewElementBuilderName << ".create()";
1876 genAddStatementEnd(FieldName, ArraySize);
Zonr Chang89273bd2010-10-14 20:57:38 +08001877 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001878
Stephen Hinesa9ae5ae2011-11-11 21:16:59 -08001879 if (mRSContext->getTargetAPI() < SLANG_ICS_TARGET_API) {
1880 // There is padding within the field type. This is only necessary
1881 // for HC-targeted APIs.
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001882 genAddPadding(FieldAllocSize - FieldStoreSize);
Stephen Hinesa9ae5ae2011-11-11 21:16:59 -08001883 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001884
1885 Pos = FieldOffset + FieldAllocSize;
1886 }
1887
1888 // There maybe some padding after the struct
Jean-Luc Brouilletc95381a2014-05-14 21:24:45 -07001889 size_t RecordAllocSize = ERT->getAllocSize();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001890
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001891 genAddPadding(RecordAllocSize - Pos);
1892 break;
1893 }
1894 default:
Stephen Hines6e6578a2011-02-07 18:05:48 -08001895 slangAssert(false && "Unknown class of type");
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001896 break;
Shih-wei Liaob1a28e72010-06-16 16:31:32 -07001897 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001898 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001899}
1900
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001901void RSReflectionJavaElementBuilder::genAddPadding(int PaddingSize) {
1902 while (PaddingSize > 0) {
1903 const std::string &VarName = createPaddingField();
1904 genAddStatementStart();
1905 if (PaddingSize >= 4) {
1906 *mOut << "Element.U32(" << mRenderScriptVar << ")";
1907 PaddingSize -= 4;
1908 } else if (PaddingSize >= 2) {
1909 *mOut << "Element.U16(" << mRenderScriptVar << ")";
1910 PaddingSize -= 2;
1911 } else if (PaddingSize >= 1) {
1912 *mOut << "Element.U8(" << mRenderScriptVar << ")";
1913 PaddingSize -= 1;
1914 }
1915 genAddStatementEnd(VarName, 0);
1916 }
1917}
1918
1919void RSReflectionJavaElementBuilder::genAddStatementStart() {
1920 mOut->indent() << mElementBuilderName << ".add(";
1921}
1922
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001923void
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001924RSReflectionJavaElementBuilder::genAddStatementEnd(const std::string &VarName,
1925 unsigned ArraySize) {
1926 *mOut << ", \"" << VarName << "\"";
1927 if (ArraySize > 0) {
1928 *mOut << ", " << ArraySize;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001929 }
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001930 *mOut << ");\n";
1931 // TODO Review incFieldIndex. It's probably better to assign the numbers at
1932 // the start rather
1933 // than as we're generating the code.
1934 mReflection->incFieldIndex();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001935}
1936
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001937/******** Methods to create Element in Java of given record type /end ********/
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001938
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -07001939bool RSReflectionJava::reflect() {
1940 std::string ErrorMsg;
1941 if (!genScriptClass(mScriptClassName, ErrorMsg)) {
1942 std::cerr << "Failed to generate class " << mScriptClassName << " ("
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001943 << ErrorMsg << ")\n";
1944 return false;
1945 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001946
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -07001947 mGeneratedFileNames->push_back(mScriptClassName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001948
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001949 // class ScriptField_<TypeName>
1950 for (RSContext::const_export_type_iterator
1951 TI = mRSContext->export_types_begin(),
1952 TE = mRSContext->export_types_end();
1953 TI != TE; TI++) {
1954 const RSExportType *ET = TI->getValue();
1955
1956 if (ET->getClass() == RSExportType::ExportClassRecord) {
1957 const RSExportRecordType *ERT =
1958 static_cast<const RSExportRecordType *>(ET);
1959
1960 if (!ERT->isArtificial() && !genTypeClass(ERT, ErrorMsg)) {
1961 std::cerr << "Failed to generate type class for struct '"
1962 << ERT->getName() << "' (" << ErrorMsg << ")\n";
1963 return false;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001964 }
1965 }
1966 }
1967
1968 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001969}
1970
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001971const char *RSReflectionJava::AccessModifierStr(AccessModifier AM) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001972 switch (AM) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001973 case AM_Public:
1974 return "public";
1975 break;
1976 case AM_Protected:
1977 return "protected";
1978 break;
1979 case AM_Private:
1980 return "private";
1981 break;
1982 case AM_PublicSynchronized:
1983 return "public synchronized";
1984 break;
1985 default:
1986 return "";
1987 break;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001988 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001989}
1990
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001991bool RSReflectionJava::startClass(AccessModifier AM, bool IsStatic,
1992 const std::string &ClassName,
1993 const char *SuperClassName,
1994 std::string &ErrorMsg) {
Zonr Chang8c6d9b22010-10-07 18:01:19 +08001995 // Open file for class
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001996 std::string FileName = ClassName + ".java";
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -07001997 if (!mOut.startFile(mOutputDirectory, FileName, mRSSourceFileName,
Stephen Hinesfc4f78b2014-06-10 18:07:10 -07001998 mRSContext->getLicenseNote(), true,
1999 mRSContext->getVerbose())) {
Zonr Chang8c6d9b22010-10-07 18:01:19 +08002000 return false;
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002001 }
Ying Wang4e348442010-08-18 10:29:12 -07002002
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002003 // Package
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002004 if (!mPackageName.empty()) {
2005 mOut << "package " << mPackageName << ";\n";
2006 }
2007 mOut << "\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002008
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002009 // Imports
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002010 mOut << "import " << mRSPackageName << ".*;\n";
Stephen Hines44d495d2014-05-22 19:42:55 -07002011 if (getEmbedBitcodeInJava()) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002012 mOut << "import " << mPackageName << "."
Stephen Hines44d495d2014-05-22 19:42:55 -07002013 << RSSlangReflectUtils::JavaBitcodeClassNameFromRSFileName(
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -07002014 mRSSourceFileName.c_str()) << ";\n";
Stephen Hines44d495d2014-05-22 19:42:55 -07002015 } else {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002016 mOut << "import android.content.res.Resources;\n";
Stephen Hines44d495d2014-05-22 19:42:55 -07002017 }
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002018 mOut << "\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002019
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002020 // All reflected classes should be annotated as hidden, so that they won't
2021 // be exposed in SDK.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002022 mOut << "/**\n";
2023 mOut << " * @hide\n";
2024 mOut << " */\n";
Ying Wang4e348442010-08-18 10:29:12 -07002025
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002026 mOut << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class "
2027 << ClassName;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002028 if (SuperClassName != NULL)
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002029 mOut << " extends " << SuperClassName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002030
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002031 mOut.startBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002032
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002033 mClassName = ClassName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002034
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002035 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002036}
2037
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002038void RSReflectionJava::endClass() {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002039 mOut.endBlock();
2040 mOut.closeFile();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002041 clear();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002042}
2043
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002044void RSReflectionJava::startTypeClass(const std::string &ClassName) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002045 mOut.indent() << "public static class " << ClassName;
2046 mOut.startBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002047}
2048
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002049void RSReflectionJava::endTypeClass() { mOut.endBlock(); }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002050
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002051void RSReflectionJava::startFunction(AccessModifier AM, bool IsStatic,
2052 const char *ReturnType,
2053 const std::string &FunctionName, int Argc,
2054 ...) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002055 ArgTy Args;
2056 va_list vl;
2057 va_start(vl, Argc);
2058
zonr6315f762010-10-05 15:35:14 +08002059 for (int i = 0; i < Argc; i++) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07002060 const char *ArgType = va_arg(vl, const char *);
2061 const char *ArgName = va_arg(vl, const char *);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002062
zonr6315f762010-10-05 15:35:14 +08002063 Args.push_back(std::make_pair(ArgType, ArgName));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002064 }
2065 va_end(vl);
2066
2067 startFunction(AM, IsStatic, ReturnType, FunctionName, Args);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002068}
2069
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002070void RSReflectionJava::startFunction(AccessModifier AM, bool IsStatic,
2071 const char *ReturnType,
2072 const std::string &FunctionName,
2073 const ArgTy &Args) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002074 mOut.indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ")
2075 << ((ReturnType) ? ReturnType : "") << " " << FunctionName
2076 << "(";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002077
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002078 bool FirstArg = true;
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07002079 for (ArgTy::const_iterator I = Args.begin(), E = Args.end(); I != E; I++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002080 if (!FirstArg)
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002081 mOut << ", ";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002082 else
2083 FirstArg = false;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002084
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002085 mOut << I->first << " " << I->second;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002086 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002087
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002088 mOut << ")";
2089 mOut.startBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002090}
2091
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002092void RSReflectionJava::endFunction() { mOut.endBlock(); }
Stephen Hinese639eb52010-11-08 19:27:20 -08002093
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002094bool RSReflectionJava::addTypeNameForElement(const std::string &TypeName) {
Stephen Hines1f6c3312012-07-03 17:23:33 -07002095 if (mTypesToCheck.find(TypeName) == mTypesToCheck.end()) {
2096 mTypesToCheck.insert(TypeName);
2097 return true;
2098 } else {
2099 return false;
2100 }
2101}
2102
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002103bool RSReflectionJava::addTypeNameForFieldPacker(const std::string &TypeName) {
Stephen Hines1f6c3312012-07-03 17:23:33 -07002104 if (mFieldPackerTypes.find(TypeName) == mFieldPackerTypes.end()) {
2105 mFieldPackerTypes.insert(TypeName);
2106 return true;
2107 } else {
2108 return false;
2109 }
2110}
2111
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07002112} // namespace slang