blob: 16b8e09d69da65dfa3fabca51fcd6ad89535c703 [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"
zonr6315f762010-10-05 15:35:14 +080040
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070041#define RS_SCRIPT_CLASS_NAME_PREFIX "ScriptC_"
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070042#define RS_SCRIPT_CLASS_SUPER_CLASS_NAME "ScriptC"
Shih-wei Liao8b1d0dd2010-07-15 18:56:55 -070043
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070044#define RS_TYPE_CLASS_SUPER_CLASS_NAME ".Script.FieldBase"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070045
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070046#define RS_TYPE_ITEM_CLASS_NAME "Item"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070047
Tim Murray3a38b742014-07-02 10:41:08 -070048#define RS_TYPE_ITEM_SIZEOF_LEGACY "Item.sizeof"
49#define RS_TYPE_ITEM_SIZEOF_CURRENT "mElement.getBytesSize()"
50
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070051#define RS_TYPE_ITEM_BUFFER_NAME "mItemArray"
52#define RS_TYPE_ITEM_BUFFER_PACKER_NAME "mIOBuffer"
53#define RS_TYPE_ELEMENT_REF_NAME "mElementCache"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070054
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070055#define RS_EXPORT_VAR_INDEX_PREFIX "mExportVarIdx_"
56#define RS_EXPORT_VAR_PREFIX "mExportVar_"
57#define RS_EXPORT_VAR_ELEM_PREFIX "mExportVarElem_"
58#define RS_EXPORT_VAR_DIM_PREFIX "mExportVarDim_"
59#define RS_EXPORT_VAR_CONST_PREFIX "const_"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070060
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070061#define RS_ELEM_PREFIX "__"
Stephen Hinesa6b54142012-04-09 18:25:08 -070062
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070063#define RS_FP_PREFIX "__rs_fp_"
Stephen Hines1f6c3312012-07-03 17:23:33 -070064
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070065#define RS_RESOURCE_NAME "__rs_resource_name"
Stephen Hinesd2936932012-09-12 20:44:32 -070066
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070067#define RS_EXPORT_FUNC_INDEX_PREFIX "mExportFuncIdx_"
68#define RS_EXPORT_FOREACH_INDEX_PREFIX "mExportForEachIdx_"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070069
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -070070#define RS_EXPORT_VAR_ALLOCATION_PREFIX "mAlloction_"
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070071#define RS_EXPORT_VAR_DATA_STORAGE_PREFIX "mData_"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070072
Stephen Hinese639eb52010-11-08 19:27:20 -080073namespace slang {
Shih-wei Liao462aefd2010-06-04 15:32:04 -070074
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -070075class RSReflectionJavaElementBuilder {
76public:
77 RSReflectionJavaElementBuilder(const char *ElementBuilderName,
78 const RSExportRecordType *ERT,
79 const char *RenderScriptVar,
80 GeneratedFile *Out, const RSContext *RSContext,
81 RSReflectionJava *Reflection);
82 void generate();
83
84private:
85 void genAddElement(const RSExportType *ET, const std::string &VarName,
86 unsigned ArraySize);
87 void genAddStatementStart();
88 void genAddStatementEnd(const std::string &VarName, unsigned ArraySize);
89 void genAddPadding(int PaddingSize);
90 // TODO Will remove later due to field name information is not necessary for
91 // C-reflect-to-Java
92 std::string createPaddingField() {
93 return mPaddingPrefix + llvm::itostr(mPaddingFieldIndex++);
94 }
95
96 const char *mElementBuilderName;
97 const RSExportRecordType *mERT;
98 const char *mRenderScriptVar;
99 GeneratedFile *mOut;
100 std::string mPaddingPrefix;
101 int mPaddingFieldIndex;
102 const RSContext *mRSContext;
103 RSReflectionJava *mReflection;
104};
105
Zonr Chang92b344a2010-10-05 20:39:03 +0800106static const char *GetMatrixTypeName(const RSExportMatrixType *EMT) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700107 static const char *MatrixTypeJavaNameMap[] = {/* 2x2 */ "Matrix2f",
108 /* 3x3 */ "Matrix3f",
109 /* 4x4 */ "Matrix4f",
Zonr Chang92b344a2010-10-05 20:39:03 +0800110 };
111 unsigned Dim = EMT->getDim();
112
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700113 if ((Dim - 2) < (sizeof(MatrixTypeJavaNameMap) / sizeof(const char *)))
114 return MatrixTypeJavaNameMap[EMT->getDim() - 2];
Zonr Chang92b344a2010-10-05 20:39:03 +0800115
Stephen Hines6e6578a2011-02-07 18:05:48 -0800116 slangAssert(false && "GetMatrixTypeName : Unsupported matrix dimension");
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700117 return nullptr;
Zonr Chang92b344a2010-10-05 20:39:03 +0800118}
119
Stephen Hines6e6578a2011-02-07 18:05:48 -0800120static const char *GetVectorAccessor(unsigned Index) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700121 static const char *VectorAccessorMap[] = {/* 0 */ "x",
122 /* 1 */ "y",
123 /* 2 */ "z",
124 /* 3 */ "w",
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700125 };
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700126
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700127 slangAssert((Index < (sizeof(VectorAccessorMap) / sizeof(const char *))) &&
Stephen Hines6e6578a2011-02-07 18:05:48 -0800128 "Out-of-bound index to access vector member");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700129
130 return VectorAccessorMap[Index];
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700131}
132
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700133static const char *GetPackerAPIName(const RSExportPrimitiveType *EPT) {
zonr6315f762010-10-05 15:35:14 +0800134 static const char *PrimitiveTypePackerAPINameMap[] = {
Pirama Arumuga Nainar7966bcf2015-04-07 11:09:14 -0700135 "addF16", // DataTypeFloat16
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700136 "addF32", // DataTypeFloat32
137 "addF64", // DataTypeFloat64
138 "addI8", // DataTypeSigned8
139 "addI16", // DataTypeSigned16
140 "addI32", // DataTypeSigned32
141 "addI64", // DataTypeSigned64
142 "addU8", // DataTypeUnsigned8
143 "addU16", // DataTypeUnsigned16
144 "addU32", // DataTypeUnsigned32
145 "addU64", // DataTypeUnsigned64
146 "addBoolean", // DataTypeBoolean
147 "addU16", // DataTypeUnsigned565
148 "addU16", // DataTypeUnsigned5551
149 "addU16", // DataTypeUnsigned4444
150 "addMatrix", // DataTypeRSMatrix2x2
151 "addMatrix", // DataTypeRSMatrix3x3
152 "addMatrix", // DataTypeRSMatrix4x4
153 "addObj", // DataTypeRSElement
154 "addObj", // DataTypeRSType
155 "addObj", // DataTypeRSAllocation
156 "addObj", // DataTypeRSSampler
157 "addObj", // DataTypeRSScript
158 "addObj", // DataTypeRSMesh
159 "addObj", // DataTypeRSPath
160 "addObj", // DataTypeRSProgramFragment
161 "addObj", // DataTypeRSProgramVertex
162 "addObj", // DataTypeRSProgramRaster
163 "addObj", // DataTypeRSProgramStore
164 "addObj", // DataTypeRSFont
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700165 };
166 unsigned TypeId = EPT->getType();
167
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700168 if (TypeId < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char *)))
169 return PrimitiveTypePackerAPINameMap[EPT->getType()];
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700170
Stephen Hines6e6578a2011-02-07 18:05:48 -0800171 slangAssert(false && "GetPackerAPIName : Unknown primitive data type");
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700172 return nullptr;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700173}
174
Stephen Hinesd369cda2012-02-13 12:00:03 -0800175static std::string GetTypeName(const RSExportType *ET, bool Brackets = true) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700176 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700177 case RSExportType::ExportClassPrimitive: {
178 return RSExportPrimitiveType::getRSReflectionType(
179 static_cast<const RSExportPrimitiveType *>(ET))->java_name;
180 }
181 case RSExportType::ExportClassPointer: {
182 const RSExportType *PointeeType =
183 static_cast<const RSExportPointerType *>(ET)->getPointeeType();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700184
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700185 if (PointeeType->getClass() != RSExportType::ExportClassRecord)
186 return "Allocation";
187 else
188 return PointeeType->getElementName();
189 }
190 case RSExportType::ExportClassVector: {
191 const RSExportVectorType *EVT = static_cast<const RSExportVectorType *>(ET);
192 std::stringstream VecName;
193 VecName << EVT->getRSReflectionType(EVT)->rs_java_vector_prefix
194 << EVT->getNumElement();
195 return VecName.str();
196 }
197 case RSExportType::ExportClassMatrix: {
198 return GetMatrixTypeName(static_cast<const RSExportMatrixType *>(ET));
199 }
200 case RSExportType::ExportClassConstantArray: {
201 const RSExportConstantArrayType *CAT =
202 static_cast<const RSExportConstantArrayType *>(ET);
203 std::string ElementTypeName = GetTypeName(CAT->getElementType());
204 if (Brackets) {
205 ElementTypeName.append("[]");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700206 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700207 return ElementTypeName;
208 }
209 case RSExportType::ExportClassRecord: {
210 return ET->getElementName() + "." RS_TYPE_ITEM_CLASS_NAME;
211 }
212 default: { slangAssert(false && "Unknown class of type"); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700213 }
214
215 return "";
216}
217
Shih-wei Liaocf950c42010-10-06 03:44:40 -0700218static const char *GetTypeNullValue(const RSExportType *ET) {
219 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700220 case RSExportType::ExportClassPrimitive: {
221 const RSExportPrimitiveType *EPT =
222 static_cast<const RSExportPrimitiveType *>(ET);
223 if (EPT->isRSObjectType())
Shih-wei Liaocf950c42010-10-06 03:44:40 -0700224 return "null";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700225 else if (EPT->getType() == DataTypeBoolean)
226 return "false";
227 else
228 return "0";
229 break;
230 }
231 case RSExportType::ExportClassPointer:
232 case RSExportType::ExportClassVector:
233 case RSExportType::ExportClassMatrix:
234 case RSExportType::ExportClassConstantArray:
235 case RSExportType::ExportClassRecord: {
236 return "null";
237 break;
238 }
239 default: { slangAssert(false && "Unknown class of type"); }
Shih-wei Liaocf950c42010-10-06 03:44:40 -0700240 }
241 return "";
242}
243
Stephen Hines47aca4e2012-03-08 20:07:28 -0800244static std::string GetBuiltinElementConstruct(const RSExportType *ET) {
Zonr Chang2e1dba62010-10-05 22:20:11 +0800245 if (ET->getClass() == RSExportType::ExportClassPrimitive) {
Stephen Hinesa6b54142012-04-09 18:25:08 -0700246 return std::string("Element.") + ET->getElementName();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700247 } else if (ET->getClass() == RSExportType::ExportClassVector) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700248 const RSExportVectorType *EVT = static_cast<const RSExportVectorType *>(ET);
Jean-Luc Brouilletcec9b652014-05-14 19:33:57 -0700249 if (EVT->getType() == DataTypeFloat32) {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -0700250 if (EVT->getNumElement() == 2) {
Stephen Hines2b8fb642012-03-09 00:12:47 -0800251 return "Element.F32_2";
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -0700252 } else if (EVT->getNumElement() == 3) {
Stephen Hines2b8fb642012-03-09 00:12:47 -0800253 return "Element.F32_3";
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -0700254 } else if (EVT->getNumElement() == 4) {
Stephen Hines2b8fb642012-03-09 00:12:47 -0800255 return "Element.F32_4";
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -0700256 } else {
257 slangAssert(false && "Vectors should be size 2, 3, 4");
258 }
Jean-Luc Brouilletcec9b652014-05-14 19:33:57 -0700259 } else if (EVT->getType() == DataTypeUnsigned8) {
Stephen Hines2b8fb642012-03-09 00:12:47 -0800260 if (EVT->getNumElement() == 4)
261 return "Element.U8_4";
Shih-wei Liao324c0472010-06-21 13:15:11 -0700262 }
Zonr Chang92b344a2010-10-05 20:39:03 +0800263 } else if (ET->getClass() == RSExportType::ExportClassMatrix) {
264 const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType *>(ET);
265 switch (EMT->getDim()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700266 case 2:
267 return "Element.MATRIX_2X2";
268 case 3:
269 return "Element.MATRIX_3X3";
270 case 4:
271 return "Element.MATRIX_4X4";
272 default:
273 slangAssert(false && "Unsupported dimension of matrix");
Zonr Chang92b344a2010-10-05 20:39:03 +0800274 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700275 }
Stephen Hines47aca4e2012-03-08 20:07:28 -0800276 // RSExportType::ExportClassPointer can't be generated in a struct.
Shih-wei Liao324c0472010-06-21 13:15:11 -0700277
Stephen Hines47aca4e2012-03-08 20:07:28 -0800278 return "";
Stephen Hines48b72bf2011-06-10 15:37:27 -0700279}
280
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700281/********************** Methods to generate script class **********************/
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -0700282RSReflectionJava::RSReflectionJava(const RSContext *Context,
283 std::vector<std::string> *GeneratedFileNames,
284 const std::string &OutputBaseDirectory,
285 const std::string &RSSourceFileName,
286 const std::string &BitCodeFileName,
287 bool EmbedBitcodeInJava)
288 : mRSContext(Context), mPackageName(Context->getReflectJavaPackageName()),
289 mRSPackageName(Context->getRSPackageName()),
290 mOutputBaseDirectory(OutputBaseDirectory),
291 mRSSourceFileName(RSSourceFileName), mBitCodeFileName(BitCodeFileName),
292 mResourceId(RSSlangReflectUtils::JavaClassNameFromRSFileName(
293 mBitCodeFileName.c_str())),
294 mScriptClassName(RS_SCRIPT_CLASS_NAME_PREFIX +
295 RSSlangReflectUtils::JavaClassNameFromRSFileName(
296 mRSSourceFileName.c_str())),
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -0700297 mEmbedBitcodeInJava(EmbedBitcodeInJava), mNextExportVarSlot(0),
298 mNextExportFuncSlot(0), mNextExportForEachSlot(0), mLastError(""),
299 mGeneratedFileNames(GeneratedFileNames), mFieldIndex(0) {
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -0700300 slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames");
301 slangAssert(!mPackageName.empty() && mPackageName != "-");
302
303 mOutputDirectory = RSSlangReflectUtils::ComputePackagedPath(
304 OutputBaseDirectory.c_str(), mPackageName.c_str()) +
305 OS_PATH_SEPARATOR_STR;
Tim Murray3a38b742014-07-02 10:41:08 -0700306
307 // mElement.getBytesSize only exists on JB+
308 if (mRSContext->getTargetAPI() >= SLANG_JB_TARGET_API) {
309 mItemSizeof = RS_TYPE_ITEM_SIZEOF_CURRENT;
310 } else {
311 mItemSizeof = RS_TYPE_ITEM_SIZEOF_LEGACY;
312 }
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -0700313}
314
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700315bool RSReflectionJava::genScriptClass(const std::string &ClassName,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -0700316 std::string &ErrorMsg) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700317 if (!startClass(AM_Public, false, ClassName, RS_SCRIPT_CLASS_SUPER_CLASS_NAME,
318 ErrorMsg))
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700319 return false;
320
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700321 genScriptClassConstructor();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700322
323 // Reflect export variable
324 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700325 E = mRSContext->export_vars_end();
326 I != E; I++)
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700327 genExportVariable(*I);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700328
Stephen Hines4a4bf922011-08-18 17:20:33 -0700329 // Reflect export for each functions (only available on ICS+)
Stephen Hines4cc499d2011-08-24 19:06:17 -0700330 if (mRSContext->getTargetAPI() >= SLANG_ICS_TARGET_API) {
Stephen Hines4a4bf922011-08-18 17:20:33 -0700331 for (RSContext::const_export_foreach_iterator
332 I = mRSContext->export_foreach_begin(),
333 E = mRSContext->export_foreach_end();
334 I != E; I++)
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700335 genExportForEach(*I);
Stephen Hines4a4bf922011-08-18 17:20:33 -0700336 }
Stephen Hines593a8942011-05-10 15:29:50 -0700337
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700338 // Reflect export function
339 for (RSContext::const_export_func_iterator
340 I = mRSContext->export_funcs_begin(),
341 E = mRSContext->export_funcs_end();
342 I != E; I++)
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700343 genExportFunction(*I);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700344
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700345 endClass();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700346
347 return true;
348}
349
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700350void RSReflectionJava::genScriptClassConstructor() {
Stephen Hines4c8b6592014-05-22 20:18:45 -0700351 std::string className(RSSlangReflectUtils::JavaBitcodeClassNameFromRSFileName(
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -0700352 mRSSourceFileName.c_str()));
Stephen Hinesd2936932012-09-12 20:44:32 -0700353 // Provide a simple way to reference this object.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700354 mOut.indent() << "private static final String " RS_RESOURCE_NAME " = \""
355 << getResourceId() << "\";\n";
Stephen Hinesd2936932012-09-12 20:44:32 -0700356
357 // Generate a simple constructor with only a single parameter (the rest
358 // can be inferred from information we already have).
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700359 mOut.indent() << "// Constructor\n";
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700360 startFunction(AM_Public, false, nullptr, getClassName(), 1, "RenderScript",
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700361 "rs");
Stephen Hines44d495d2014-05-22 19:42:55 -0700362
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700363 if (getEmbedBitcodeInJava()) {
Stephen Hines4c8b6592014-05-22 20:18:45 -0700364 // Call new single argument Java-only constructor
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700365 mOut.indent() << "super(rs,\n";
366 mOut.indent() << " " << RS_RESOURCE_NAME ",\n";
367 mOut.indent() << " " << className << ".getBitCode32(),\n";
Stephen Hines9ae18b22014-06-10 23:53:00 -0700368 mOut.indent() << " " << className << ".getBitCode64());\n";
Stephen Hines4c8b6592014-05-22 20:18:45 -0700369 } else {
370 // Call alternate constructor with required parameters.
371 // Look up the proper raw bitcode resource id via the context.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700372 mOut.indent() << "this(rs,\n";
373 mOut.indent() << " rs.getApplicationContext().getResources(),\n";
374 mOut.indent() << " rs.getApplicationContext().getResources()."
375 "getIdentifier(\n";
376 mOut.indent() << " " RS_RESOURCE_NAME ", \"raw\",\n";
377 mOut.indent()
378 << " rs.getApplicationContext().getPackageName()));\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700379 endFunction();
Stephen Hinesd2936932012-09-12 20:44:32 -0700380
Stephen Hines4c8b6592014-05-22 20:18:45 -0700381 // Alternate constructor (legacy) with 3 original parameters.
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700382 startFunction(AM_Public, false, nullptr, getClassName(), 3, "RenderScript",
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700383 "rs", "Resources", "resources", "int", "id");
Stephen Hines4c8b6592014-05-22 20:18:45 -0700384 // Call constructor of super class
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700385 mOut.indent() << "super(rs, resources, id);\n";
Stephen Hines4c8b6592014-05-22 20:18:45 -0700386 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700387
388 // If an exported variable has initial value, reflect it
389
390 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700391 E = mRSContext->export_vars_end();
392 I != E; I++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700393 const RSExportVar *EV = *I;
Stephen Hinesd369cda2012-02-13 12:00:03 -0800394 if (!EV->getInit().isUninit()) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700395 genInitExportVariable(EV->getType(), EV->getName(), EV->getInit());
Stephen Hinesd369cda2012-02-13 12:00:03 -0800396 } else if (EV->getArraySize()) {
397 // Always create an initial zero-init array object.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700398 mOut.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = new "
399 << GetTypeName(EV->getType(), false) << "["
400 << EV->getArraySize() << "];\n";
Stephen Hinesd369cda2012-02-13 12:00:03 -0800401 size_t NumInits = EV->getNumInits();
402 const RSExportConstantArrayType *ECAT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700403 static_cast<const RSExportConstantArrayType *>(EV->getType());
Stephen Hinesd369cda2012-02-13 12:00:03 -0800404 const RSExportType *ET = ECAT->getElementType();
405 for (size_t i = 0; i < NumInits; i++) {
406 std::stringstream Name;
407 Name << EV->getName() << "[" << i << "]";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700408 genInitExportVariable(ET, Name.str(), EV->getInitArray(i));
Stephen Hinesd369cda2012-02-13 12:00:03 -0800409 }
410 }
Stephen Hinesa6b54142012-04-09 18:25:08 -0700411 if (mRSContext->getTargetAPI() >= SLANG_JB_TARGET_API) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700412 genTypeInstance(EV->getType());
Stephen Hinesa6b54142012-04-09 18:25:08 -0700413 }
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700414 genFieldPackerInstance(EV->getType());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700415 }
416
Stephen Hines48b72bf2011-06-10 15:37:27 -0700417 for (RSContext::const_export_foreach_iterator
418 I = mRSContext->export_foreach_begin(),
419 E = mRSContext->export_foreach_end();
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700420 I != E; I++) {
Stephen Hines48b72bf2011-06-10 15:37:27 -0700421 const RSExportForEach *EF = *I;
422
Chris Wailesc9454af2014-06-13 17:25:40 -0700423 const RSExportForEach::InTypeVec &InTypes = EF->getInTypes();
424 for (RSExportForEach::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
425 BI != EI; BI++) {
426
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700427 if (*BI != nullptr) {
Chris Wailesc9454af2014-06-13 17:25:40 -0700428 genTypeInstanceFromPointer(*BI);
429 }
Stephen Hines48b72bf2011-06-10 15:37:27 -0700430 }
Chris Wailesc9454af2014-06-13 17:25:40 -0700431
Stephen Hines48b72bf2011-06-10 15:37:27 -0700432 const RSExportType *OET = EF->getOutType();
433 if (OET) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700434 genTypeInstanceFromPointer(OET);
Stephen Hines48b72bf2011-06-10 15:37:27 -0700435 }
436 }
437
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700438 endFunction();
Jason Samsb6902e22010-11-03 17:04:06 -0700439
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700440 for (std::set<std::string>::iterator I = mTypesToCheck.begin(),
441 E = mTypesToCheck.end();
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700442 I != E; I++) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700443 mOut.indent() << "private Element " RS_ELEM_PREFIX << *I << ";\n";
Stephen Hines48b72bf2011-06-10 15:37:27 -0700444 }
445
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700446 for (std::set<std::string>::iterator I = mFieldPackerTypes.begin(),
447 E = mFieldPackerTypes.end();
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700448 I != E; I++) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700449 mOut.indent() << "private FieldPacker " RS_FP_PREFIX << *I << ";\n";
Stephen Hines1f6c3312012-07-03 17:23:33 -0700450 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700451}
452
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700453void RSReflectionJava::genInitBoolExportVariable(const std::string &VarName,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -0700454 const clang::APValue &Val) {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800455 slangAssert(!Val.isUninit() && "Not a valid initializer");
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700456 slangAssert((Val.getKind() == clang::APValue::Int) &&
457 "Bool type has wrong initial APValue");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700458
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700459 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700460
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700461 mOut << ((Val.getInt().getSExtValue() == 0) ? "false" : "true") << ";\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700462}
463
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700464void
465RSReflectionJava::genInitPrimitiveExportVariable(const std::string &VarName,
466 const clang::APValue &Val) {
Stephen Hines5d671782012-01-31 19:32:04 -0800467 slangAssert(!Val.isUninit() && "Not a valid initializer");
468
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700469 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -0700470 genInitValue(Val, false);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700471 mOut << ";\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700472}
473
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700474void RSReflectionJava::genInitExportVariable(const RSExportType *ET,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -0700475 const std::string &VarName,
476 const clang::APValue &Val) {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800477 slangAssert(!Val.isUninit() && "Not a valid initializer");
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700478
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700479 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700480 case RSExportType::ExportClassPrimitive: {
481 const RSExportPrimitiveType *EPT =
482 static_cast<const RSExportPrimitiveType *>(ET);
483 if (EPT->getType() == DataTypeBoolean) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700484 genInitBoolExportVariable(VarName, Val);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700485 } else {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700486 genInitPrimitiveExportVariable(VarName, Val);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700487 }
488 break;
489 }
490 case RSExportType::ExportClassPointer: {
491 if (!Val.isInt() || Val.getInt().getSExtValue() != 0)
492 std::cout << "Initializer which is non-NULL to pointer type variable "
493 "will be ignored\n";
494 break;
495 }
496 case RSExportType::ExportClassVector: {
497 const RSExportVectorType *EVT = static_cast<const RSExportVectorType *>(ET);
498 switch (Val.getKind()) {
499 case clang::APValue::Int:
500 case clang::APValue::Float: {
501 for (unsigned i = 0; i < EVT->getNumElement(); i++) {
502 std::string Name = VarName + "." + GetVectorAccessor(i);
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700503 genInitPrimitiveExportVariable(Name, Val);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700504 }
505 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700506 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700507 case clang::APValue::Vector: {
508 std::stringstream VecName;
509 VecName << EVT->getRSReflectionType(EVT)->rs_java_vector_prefix
510 << EVT->getNumElement();
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700511 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new "
512 << VecName.str() << "();\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700513
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700514 unsigned NumElements = std::min(
515 static_cast<unsigned>(EVT->getNumElement()), Val.getVectorLength());
516 for (unsigned i = 0; i < NumElements; i++) {
517 const clang::APValue &ElementVal = Val.getVectorElt(i);
518 std::string Name = VarName + "." + GetVectorAccessor(i);
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700519 genInitPrimitiveExportVariable(Name, ElementVal);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700520 }
521 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700522 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700523 case clang::APValue::MemberPointer:
524 case clang::APValue::Uninitialized:
525 case clang::APValue::ComplexInt:
526 case clang::APValue::ComplexFloat:
527 case clang::APValue::LValue:
528 case clang::APValue::Array:
529 case clang::APValue::Struct:
530 case clang::APValue::Union:
531 case clang::APValue::AddrLabelDiff: {
532 slangAssert(false && "Unexpected type of value of initializer.");
533 }
534 }
535 break;
536 }
537 // TODO(zonr): Resolving initializer of a record (and matrix) type variable
538 // is complex. It cannot obtain by just simply evaluating the initializer
539 // expression.
540 case RSExportType::ExportClassMatrix:
541 case RSExportType::ExportClassConstantArray:
542 case RSExportType::ExportClassRecord: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700543#if 0
544 unsigned InitIndex = 0;
zonr6315f762010-10-05 15:35:14 +0800545 const RSExportRecordType *ERT =
546 static_cast<const RSExportRecordType*>(ET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700547
Stephen Hines6e6578a2011-02-07 18:05:48 -0800548 slangAssert((Val.getKind() == clang::APValue::Vector) &&
549 "Unexpected type of initializer for record type variable");
Shih-wei Liao9c631ff2010-09-17 11:57:29 -0700550
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700551 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName
Stephen Hinesa6b54142012-04-09 18:25:08 -0700552 << " = new " << ERT->getElementName()
Jean-Luc Brouillet29689212014-05-27 13:25:31 -0700553 << "." RS_TYPE_ITEM_CLASS_NAME"();\n";
Shih-wei Liao9c631ff2010-09-17 11:57:29 -0700554
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700555 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
556 E = ERT->fields_end();
557 I != E;
558 I++) {
559 const RSExportRecordType::Field *F = *I;
560 std::string FieldName = VarName + "." + F->getName();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700561
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700562 if (InitIndex > Val.getVectorLength())
563 break;
564
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700565 genInitPrimitiveExportVariable(FieldName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700566 Val.getVectorElt(InitIndex++));
567 }
568#endif
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700569 slangAssert(false && "Unsupported initializer for record/matrix/constant "
570 "array type variable currently");
571 break;
572 }
573 default: { slangAssert(false && "Unknown class of type"); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700574 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700575}
576
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700577void RSReflectionJava::genExportVariable(const RSExportVar *EV) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700578 const RSExportType *ET = EV->getType();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700579
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700580 mOut.indent() << "private final static int " << RS_EXPORT_VAR_INDEX_PREFIX
581 << EV->getName() << " = " << getNextExportVarSlot() << ";\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700582
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700583 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700584 case RSExportType::ExportClassPrimitive: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700585 genPrimitiveTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700586 break;
587 }
588 case RSExportType::ExportClassPointer: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700589 genPointerTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700590 break;
591 }
592 case RSExportType::ExportClassVector: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700593 genVectorTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700594 break;
595 }
596 case RSExportType::ExportClassMatrix: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700597 genMatrixTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700598 break;
599 }
600 case RSExportType::ExportClassConstantArray: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700601 genConstantArrayTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700602 break;
603 }
604 case RSExportType::ExportClassRecord: {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700605 genRecordTypeExportVariable(EV);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700606 break;
607 }
608 default: { slangAssert(false && "Unknown class of type"); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700609 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700610}
611
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700612void RSReflectionJava::genExportFunction(const RSExportFunc *EF) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700613 mOut.indent() << "private final static int " << RS_EXPORT_FUNC_INDEX_PREFIX
614 << EF->getName() << " = " << getNextExportFuncSlot() << ";\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700615
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700616 // invoke_*()
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700617 ArgTy Args;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700618
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800619 if (EF->hasParam()) {
620 for (RSExportFunc::const_param_iterator I = EF->params_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700621 E = EF->params_end();
622 I != E; I++) {
623 Args.push_back(
624 std::make_pair(GetTypeName((*I)->getType()), (*I)->getName()));
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800625 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700626 }
627
Stephen Hinesb3e022a2015-05-21 09:44:14 -0700628 if (mRSContext->getTargetAPI() >= SLANG_M_TARGET_API) {
Yang Nicec2a1d2014-12-02 10:23:47 -0800629 startFunction(AM_Public, false, "Script.InvokeID",
630 "getInvokeID_" + EF->getName(), 0);
631
632 mOut.indent() << "return createInvokeID(" << RS_EXPORT_FUNC_INDEX_PREFIX
633 << EF->getName() << ");\n";
634
635 endFunction();
636 }
637
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700638 startFunction(AM_Public, false, "void",
639 "invoke_" + EF->getName(/*Mangle=*/false),
640 // We are using un-mangled name since Java
641 // supports method overloading.
642 Args);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700643
644 if (!EF->hasParam()) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700645 mOut.indent() << "invoke(" << RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName()
646 << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700647 } else {
648 const RSExportRecordType *ERT = EF->getParamPacketType();
649 std::string FieldPackerName = EF->getName() + "_fp";
650
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700651 if (genCreateFieldPacker(ERT, FieldPackerName.c_str()))
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700652 genPackVarOfType(ERT, nullptr, FieldPackerName.c_str());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700653
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700654 mOut.indent() << "invoke(" << RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName()
655 << ", " << FieldPackerName << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700656 }
657
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700658 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700659}
660
Chris Wailesc9454af2014-06-13 17:25:40 -0700661void RSReflectionJava::genPairwiseDimCheck(std::string name0,
662 std::string name1) {
663
664 mOut.indent() << "// Verify dimensions\n";
665 mOut.indent() << "t0 = " << name0 << ".getType();\n";
666 mOut.indent() << "t1 = " << name1 << ".getType();\n";
667 mOut.indent() << "if ((t0.getCount() != t1.getCount()) ||\n";
668 mOut.indent() << " (t0.getX() != t1.getX()) ||\n";
669 mOut.indent() << " (t0.getY() != t1.getY()) ||\n";
670 mOut.indent() << " (t0.getZ() != t1.getZ()) ||\n";
671 mOut.indent() << " (t0.hasFaces() != t1.hasFaces()) ||\n";
672 mOut.indent() << " (t0.hasMipmaps() != t1.hasMipmaps())) {\n";
673 mOut.indent() << " throw new RSRuntimeException(\"Dimension mismatch "
674 << "between parameters " << name0 << " and " << name1
675 << "!\");\n";
676 mOut.indent() << "}\n\n";
677}
678
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700679void RSReflectionJava::genExportForEach(const RSExportForEach *EF) {
Stephen Hinesc17e1982012-02-22 12:30:45 -0800680 if (EF->isDummyRoot()) {
681 // Skip reflection for dummy root() kernels. Note that we have to
682 // advance the next slot number for ForEach, however.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700683 mOut.indent() << "//private final static int "
684 << RS_EXPORT_FOREACH_INDEX_PREFIX << EF->getName() << " = "
685 << getNextExportForEachSlot() << ";\n";
Stephen Hinesc17e1982012-02-22 12:30:45 -0800686 return;
687 }
688
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700689 mOut.indent() << "private final static int " << RS_EXPORT_FOREACH_INDEX_PREFIX
690 << EF->getName() << " = " << getNextExportForEachSlot()
691 << ";\n";
Stephen Hines593a8942011-05-10 15:29:50 -0700692
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700693 // forEach_*()
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700694 ArgTy Args;
David Grossfb78d4c2015-03-31 13:56:05 -0700695 bool HasAllocation = false; // at least one in/out allocation?
Stephen Hines593a8942011-05-10 15:29:50 -0700696
Chris Wailesc9454af2014-06-13 17:25:40 -0700697 const RSExportForEach::InVec &Ins = EF->getIns();
698 const RSExportForEach::InTypeVec &InTypes = EF->getInTypes();
699 const RSExportType *OET = EF->getOutType();
700
701 if (Ins.size() == 1) {
David Grossfb78d4c2015-03-31 13:56:05 -0700702 HasAllocation = true;
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700703 Args.push_back(std::make_pair("Allocation", "ain"));
Chris Wailesc9454af2014-06-13 17:25:40 -0700704
705 } else if (Ins.size() > 1) {
David Grossfb78d4c2015-03-31 13:56:05 -0700706 HasAllocation = true;
Chris Wailesc9454af2014-06-13 17:25:40 -0700707 for (RSExportForEach::InIter BI = Ins.begin(), EI = Ins.end(); BI != EI;
708 BI++) {
709
710 Args.push_back(std::make_pair("Allocation",
711 "ain_" + (*BI)->getName().str()));
712 }
713 }
714
David Grossfb78d4c2015-03-31 13:56:05 -0700715 if (EF->hasOut() || EF->hasReturn()) {
716 HasAllocation = true;
Stephen Hines593a8942011-05-10 15:29:50 -0700717 Args.push_back(std::make_pair("Allocation", "aout"));
David Grossfb78d4c2015-03-31 13:56:05 -0700718 }
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700719
720 const RSExportRecordType *ERT = EF->getParamPacketType();
721 if (ERT) {
722 for (RSExportForEach::const_param_iterator I = EF->params_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700723 E = EF->params_end();
724 I != E; I++) {
725 Args.push_back(
726 std::make_pair(GetTypeName((*I)->getType()), (*I)->getName()));
Stephen Hines593a8942011-05-10 15:29:50 -0700727 }
728 }
729
Tim Murrayb81a9932012-10-10 15:56:02 -0700730 if (mRSContext->getTargetAPI() >= SLANG_JB_MR1_TARGET_API) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700731 startFunction(AM_Public, false, "Script.KernelID",
732 "getKernelID_" + EF->getName(), 0);
Tim Murrayb81a9932012-10-10 15:56:02 -0700733
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700734 // TODO: add element checking
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700735 mOut.indent() << "return createKernelID(" << RS_EXPORT_FOREACH_INDEX_PREFIX
Chris Wailesc9454af2014-06-13 17:25:40 -0700736 << EF->getName() << ", " << EF->getSignatureMetadata()
737 << ", null, null);\n";
Tim Murrayb81a9932012-10-10 15:56:02 -0700738
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700739 endFunction();
Tim Murrayb81a9932012-10-10 15:56:02 -0700740 }
741
Stephen Hines50974742013-02-12 22:11:08 -0800742 if (mRSContext->getTargetAPI() >= SLANG_JB_MR2_TARGET_API) {
David Grossfb78d4c2015-03-31 13:56:05 -0700743 if (HasAllocation) {
744 startFunction(AM_Public, false, "void", "forEach_" + EF->getName(), Args);
Stephen Hines50974742013-02-12 22:11:08 -0800745
David Grossfb78d4c2015-03-31 13:56:05 -0700746 mOut.indent() << "forEach_" << EF->getName();
747 mOut << "(";
Stephen Hines50974742013-02-12 22:11:08 -0800748
David Grossfb78d4c2015-03-31 13:56:05 -0700749 if (Ins.size() == 1) {
750 mOut << "ain, ";
Chris Wailesc9454af2014-06-13 17:25:40 -0700751
David Grossfb78d4c2015-03-31 13:56:05 -0700752 } else if (Ins.size() > 1) {
753 for (RSExportForEach::InIter BI = Ins.begin(), EI = Ins.end(); BI != EI;
754 BI++) {
Chris Wailesc9454af2014-06-13 17:25:40 -0700755
David Grossfb78d4c2015-03-31 13:56:05 -0700756 mOut << "ain_" << (*BI)->getName().str() << ", ";
757 }
Chris Wailesc9454af2014-06-13 17:25:40 -0700758 }
David Grossfb78d4c2015-03-31 13:56:05 -0700759
760 if (EF->hasOut() || EF->hasReturn()) {
761 mOut << "aout, ";
762 }
763
764 if (EF->hasUsrData()) {
765 mOut << Args.back().second << ", ";
766 }
767
768 // No clipped bounds to pass in.
769 mOut << "null);\n";
770
771 endFunction();
Stephen Hines50974742013-02-12 22:11:08 -0800772 }
773
Stephen Hines50974742013-02-12 22:11:08 -0800774 // Add the clipped kernel parameters to the Args list.
775 Args.push_back(std::make_pair("Script.LaunchOptions", "sc"));
776 }
777
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700778 startFunction(AM_Public, false, "void", "forEach_" + EF->getName(), Args);
Stephen Hines593a8942011-05-10 15:29:50 -0700779
Chris Wailesc9454af2014-06-13 17:25:40 -0700780 if (InTypes.size() == 1) {
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700781 if (InTypes.front() != nullptr) {
Chris Wailesc9454af2014-06-13 17:25:40 -0700782 genTypeCheck(InTypes.front(), "ain");
783 }
784
785 } else if (InTypes.size() > 1) {
786 size_t Index = 0;
787 for (RSExportForEach::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
788 BI != EI; BI++, ++Index) {
789
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700790 if (*BI != nullptr) {
Chris Wailesc9454af2014-06-13 17:25:40 -0700791 genTypeCheck(*BI, ("ain_" + Ins[Index]->getName()).str().c_str());
792 }
793 }
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700794 }
Chris Wailesc9454af2014-06-13 17:25:40 -0700795
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700796 if (OET) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700797 genTypeCheck(OET, "aout");
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700798 }
799
Chris Wailesc9454af2014-06-13 17:25:40 -0700800 if (Ins.size() == 1 && (EF->hasOut() || EF->hasReturn())) {
801 mOut.indent() << "Type t0, t1;";
802 genPairwiseDimCheck("ain", "aout");
803
804 } else if (Ins.size() > 1) {
805 mOut.indent() << "Type t0, t1;";
806
807 std::string In0Name = "ain_" + Ins[0]->getName().str();
808
809 for (size_t index = 1; index < Ins.size(); ++index) {
810 genPairwiseDimCheck(In0Name, "ain_" + Ins[index]->getName().str());
811 }
812
813 if (EF->hasOut() || EF->hasReturn()) {
814 genPairwiseDimCheck(In0Name, "aout");
815 }
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700816 }
817
818 std::string FieldPackerName = EF->getName() + "_fp";
819 if (ERT) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700820 if (genCreateFieldPacker(ERT, FieldPackerName.c_str())) {
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700821 genPackVarOfType(ERT, nullptr, FieldPackerName.c_str());
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700822 }
Stephen Hines593a8942011-05-10 15:29:50 -0700823 }
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700824 mOut.indent() << "forEach(" << RS_EXPORT_FOREACH_INDEX_PREFIX
825 << EF->getName();
Stephen Hines593a8942011-05-10 15:29:50 -0700826
Chris Wailesc9454af2014-06-13 17:25:40 -0700827 if (Ins.size() == 1) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700828 mOut << ", ain";
Chris Wailesc9454af2014-06-13 17:25:40 -0700829 } else if (Ins.size() > 1) {
830 mOut << ", new Allocation[]{ain_" << Ins[0]->getName().str();
831
832 for (size_t index = 1; index < Ins.size(); ++index) {
833 mOut << ", ain_" << Ins[index]->getName().str();
834 }
835
836 mOut << "}";
837
838 } else {
839 mOut << ", (Allocation) null";
840 }
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700841
Stephen Hines9ca96e72012-09-13 16:57:06 -0700842 if (EF->hasOut() || EF->hasReturn())
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700843 mOut << ", aout";
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700844 else
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700845 mOut << ", null";
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700846
847 if (EF->hasUsrData())
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700848 mOut << ", " << FieldPackerName;
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700849 else
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700850 mOut << ", null";
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700851
Stephen Hines50974742013-02-12 22:11:08 -0800852 if (mRSContext->getTargetAPI() >= SLANG_JB_MR2_TARGET_API) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700853 mOut << ", sc);\n";
Stephen Hines50974742013-02-12 22:11:08 -0800854 } else {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700855 mOut << ");\n";
Stephen Hines50974742013-02-12 22:11:08 -0800856 }
Stephen Hines593a8942011-05-10 15:29:50 -0700857
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700858 endFunction();
Stephen Hines593a8942011-05-10 15:29:50 -0700859}
860
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700861void RSReflectionJava::genTypeInstanceFromPointer(const RSExportType *ET) {
Stephen Hines48b72bf2011-06-10 15:37:27 -0700862 if (ET->getClass() == RSExportType::ExportClassPointer) {
Stephen Hines9ca96e72012-09-13 16:57:06 -0700863 // For pointer parameters to original forEach kernels.
Stephen Hines48b72bf2011-06-10 15:37:27 -0700864 const RSExportPointerType *EPT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700865 static_cast<const RSExportPointerType *>(ET);
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700866 genTypeInstance(EPT->getPointeeType());
Stephen Hines9ca96e72012-09-13 16:57:06 -0700867 } else {
868 // For handling pass-by-value kernel parameters.
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700869 genTypeInstance(ET);
Stephen Hinesa6b54142012-04-09 18:25:08 -0700870 }
871}
Stephen Hines48b72bf2011-06-10 15:37:27 -0700872
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700873void RSReflectionJava::genTypeInstance(const RSExportType *ET) {
Stephen Hinesa6b54142012-04-09 18:25:08 -0700874 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700875 case RSExportType::ExportClassPrimitive:
876 case RSExportType::ExportClassVector:
877 case RSExportType::ExportClassConstantArray: {
878 std::string TypeName = ET->getElementName();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700879 if (addTypeNameForElement(TypeName)) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700880 mOut.indent() << RS_ELEM_PREFIX << TypeName << " = Element." << TypeName
881 << "(rs);\n";
Stephen Hines48b72bf2011-06-10 15:37:27 -0700882 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700883 break;
884 }
Stephen Hinesa6b54142012-04-09 18:25:08 -0700885
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700886 case RSExportType::ExportClassRecord: {
887 std::string ClassName = ET->getElementName();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700888 if (addTypeNameForElement(ClassName)) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700889 mOut.indent() << RS_ELEM_PREFIX << ClassName << " = " << ClassName
890 << ".createElement(rs);\n";
Stephen Hinesa6b54142012-04-09 18:25:08 -0700891 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700892 break;
893 }
Stephen Hinesa6b54142012-04-09 18:25:08 -0700894
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700895 default:
896 break;
Stephen Hines48b72bf2011-06-10 15:37:27 -0700897 }
898}
899
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700900void RSReflectionJava::genFieldPackerInstance(const RSExportType *ET) {
Stephen Hines1f6c3312012-07-03 17:23:33 -0700901 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700902 case RSExportType::ExportClassPrimitive:
903 case RSExportType::ExportClassVector:
904 case RSExportType::ExportClassConstantArray:
905 case RSExportType::ExportClassRecord: {
906 std::string TypeName = ET->getElementName();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700907 addTypeNameForFieldPacker(TypeName);
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700908 break;
909 }
Stephen Hines1f6c3312012-07-03 17:23:33 -0700910
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700911 default:
912 break;
Stephen Hines1f6c3312012-07-03 17:23:33 -0700913 }
914}
915
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700916void RSReflectionJava::genTypeCheck(const RSExportType *ET,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -0700917 const char *VarName) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700918 mOut.indent() << "// check " << VarName << "\n";
Stephen Hines48b72bf2011-06-10 15:37:27 -0700919
920 if (ET->getClass() == RSExportType::ExportClassPointer) {
921 const RSExportPointerType *EPT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700922 static_cast<const RSExportPointerType *>(ET);
Stephen Hines48b72bf2011-06-10 15:37:27 -0700923 ET = EPT->getPointeeType();
924 }
925
926 std::string TypeName;
927
928 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700929 case RSExportType::ExportClassPrimitive:
930 case RSExportType::ExportClassVector:
931 case RSExportType::ExportClassRecord: {
932 TypeName = ET->getElementName();
933 break;
934 }
Stephen Hines48b72bf2011-06-10 15:37:27 -0700935
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700936 default:
937 break;
Stephen Hines48b72bf2011-06-10 15:37:27 -0700938 }
939
940 if (!TypeName.empty()) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700941 mOut.indent() << "if (!" << VarName
942 << ".getType().getElement().isCompatible(" RS_ELEM_PREFIX
943 << TypeName << ")) {\n";
944 mOut.indent() << " throw new RSRuntimeException(\"Type mismatch with "
945 << TypeName << "!\");\n";
946 mOut.indent() << "}\n";
Stephen Hines48b72bf2011-06-10 15:37:27 -0700947 }
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700948}
949
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700950void RSReflectionJava::genPrimitiveTypeExportVariable(const RSExportVar *EV) {
Jean-Luc Brouillet602def72014-05-27 16:11:37 -0700951 slangAssert(
952 (EV->getType()->getClass() == RSExportType::ExportClassPrimitive) &&
953 "Variable should be type of primitive here");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700954
955 const RSExportPrimitiveType *EPT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -0700956 static_cast<const RSExportPrimitiveType *>(EV->getType());
Stephen Hines0d26cef2012-05-01 19:23:01 -0700957 std::string TypeName = GetTypeName(EPT);
958 std::string VarName = EV->getName();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700959
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700960 genPrivateExportVariable(TypeName, EV->getName());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700961
Stephen Hines5d671782012-01-31 19:32:04 -0800962 if (EV->isConst()) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700963 mOut.indent() << "public final static " << TypeName
964 << " " RS_EXPORT_VAR_CONST_PREFIX << VarName << " = ";
Stephen Hines5d671782012-01-31 19:32:04 -0800965 const clang::APValue &Val = EV->getInit();
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -0700966 genInitValue(Val, EPT->getType() == DataTypeBoolean);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700967 mOut << ";\n";
Stephen Hines5d671782012-01-31 19:32:04 -0800968 } else {
969 // set_*()
Stephen Hines1f6c3312012-07-03 17:23:33 -0700970 // This must remain synchronized, since multiple Dalvik threads may
971 // be calling setters.
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700972 startFunction(AM_PublicSynchronized, false, "void", "set_" + VarName, 1,
973 TypeName.c_str(), "v");
Stephen Hinesbcae1fe2012-09-25 19:17:33 -0700974 if ((EPT->getSize() < 4) || EV->isUnsigned()) {
Stephen Hines1f6c3312012-07-03 17:23:33 -0700975 // We create/cache a per-type FieldPacker. This allows us to reuse the
976 // validation logic (for catching negative inputs from Dalvik, as well
977 // as inputs that are too large to be represented in the unsigned type).
Stephen Hinesbcae1fe2012-09-25 19:17:33 -0700978 // Sub-integer types are also handled specially here, so that we don't
979 // overwrite bytes accidentally.
Stephen Hines1f6c3312012-07-03 17:23:33 -0700980 std::string ElemName = EPT->getElementName();
981 std::string FPName;
982 FPName = RS_FP_PREFIX + ElemName;
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700983 mOut.indent() << "if (" << FPName << "!= null) {\n";
984 mOut.increaseIndent();
985 mOut.indent() << FPName << ".reset();\n";
986 mOut.decreaseIndent();
987 mOut.indent() << "} else {\n";
988 mOut.increaseIndent();
989 mOut.indent() << FPName << " = new FieldPacker(" << EPT->getSize()
990 << ");\n";
991 mOut.decreaseIndent();
992 mOut.indent() << "}\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700993
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -0700994 genPackVarOfType(EPT, "v", FPName.c_str());
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700995 mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
996 << ", " << FPName << ");\n";
Stephen Hines1f6c3312012-07-03 17:23:33 -0700997 } else {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -0700998 mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
999 << ", v);\n";
Stephen Hines1f6c3312012-07-03 17:23:33 -07001000 }
1001
1002 // Dalvik update comes last, since the input may be invalid (and hence
1003 // throw an exception).
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001004 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001005
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001006 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001007 }
Shih-wei Liao9e86e192010-06-18 20:42:28 -07001008
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001009 genGetExportVariable(TypeName, VarName);
1010 genGetFieldID(VarName);
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001011}
1012
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001013void RSReflectionJava::genInitValue(const clang::APValue &Val, bool asBool) {
1014 switch (Val.getKind()) {
1015 case clang::APValue::Int: {
1016 llvm::APInt api = Val.getInt();
1017 if (asBool) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001018 mOut << ((api.getSExtValue() == 0) ? "false" : "true");
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001019 } else {
1020 // TODO: Handle unsigned correctly
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001021 mOut << api.getSExtValue();
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001022 if (api.getBitWidth() > 32) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001023 mOut << "L";
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001024 }
1025 }
1026 break;
1027 }
1028
1029 case clang::APValue::Float: {
1030 llvm::APFloat apf = Val.getFloat();
1031 llvm::SmallString<30> s;
1032 apf.toString(s);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001033 mOut << s.c_str();
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001034 if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) {
1035 if (s.count('.') == 0) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001036 mOut << ".f";
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001037 } else {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001038 mOut << "f";
Jean-Luc Brouilletefcff102014-06-03 16:13:51 -07001039 }
1040 }
1041 break;
1042 }
1043
1044 case clang::APValue::ComplexInt:
1045 case clang::APValue::ComplexFloat:
1046 case clang::APValue::LValue:
1047 case clang::APValue::Vector: {
1048 slangAssert(false && "Primitive type cannot have such kind of initializer");
1049 break;
1050 }
1051
1052 default: { slangAssert(false && "Unknown kind of initializer"); }
1053 }
1054}
1055
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001056void RSReflectionJava::genPointerTypeExportVariable(const RSExportVar *EV) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001057 const RSExportType *ET = EV->getType();
1058 const RSExportType *PointeeType;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001059
Stephen Hines6e6578a2011-02-07 18:05:48 -08001060 slangAssert((ET->getClass() == RSExportType::ExportClassPointer) &&
1061 "Variable should be type of pointer here");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001062
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001063 PointeeType = static_cast<const RSExportPointerType *>(ET)->getPointeeType();
Stephen Hines0d26cef2012-05-01 19:23:01 -07001064 std::string TypeName = GetTypeName(ET);
1065 std::string VarName = EV->getName();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001066
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001067 genPrivateExportVariable(TypeName, VarName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001068
Zonr Chang89273bd2010-10-14 20:57:38 +08001069 // bind_*()
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001070 startFunction(AM_Public, false, "void", "bind_" + VarName, 1,
1071 TypeName.c_str(), "v");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001072
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001073 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
1074 mOut.indent() << "if (v == null) bindAllocation(null, "
1075 << RS_EXPORT_VAR_INDEX_PREFIX << VarName << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001076
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001077 if (PointeeType->getClass() == RSExportType::ExportClassRecord) {
1078 mOut.indent() << "else bindAllocation(v.getAllocation(), "
1079 << RS_EXPORT_VAR_INDEX_PREFIX << VarName << ");\n";
1080 } else {
1081 mOut.indent() << "else bindAllocation(v, " << RS_EXPORT_VAR_INDEX_PREFIX
1082 << VarName << ");\n";
1083 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001084
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001085 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001086
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001087 genGetExportVariable(TypeName, VarName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001088}
1089
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001090void RSReflectionJava::genVectorTypeExportVariable(const RSExportVar *EV) {
Stephen Hines6e6578a2011-02-07 18:05:48 -08001091 slangAssert((EV->getType()->getClass() == RSExportType::ExportClassVector) &&
1092 "Variable should be type of vector here");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001093
Stephen Hines0d26cef2012-05-01 19:23:01 -07001094 std::string TypeName = GetTypeName(EV->getType());
1095 std::string VarName = EV->getName();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001096
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001097 genPrivateExportVariable(TypeName, VarName);
1098 genSetExportVariable(TypeName, EV);
1099 genGetExportVariable(TypeName, VarName);
1100 genGetFieldID(VarName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001101}
1102
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001103void RSReflectionJava::genMatrixTypeExportVariable(const RSExportVar *EV) {
Stephen Hines6e6578a2011-02-07 18:05:48 -08001104 slangAssert((EV->getType()->getClass() == RSExportType::ExportClassMatrix) &&
1105 "Variable should be type of matrix here");
Zonr Chang92b344a2010-10-05 20:39:03 +08001106
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001107 const RSExportType *ET = EV->getType();
Stephen Hines0d26cef2012-05-01 19:23:01 -07001108 std::string TypeName = GetTypeName(ET);
1109 std::string VarName = EV->getName();
Zonr Chang92b344a2010-10-05 20:39:03 +08001110
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001111 genPrivateExportVariable(TypeName, VarName);
Zonr Chang92b344a2010-10-05 20:39:03 +08001112
1113 // set_*()
1114 if (!EV->isConst()) {
Stephen Hines0d26cef2012-05-01 19:23:01 -07001115 const char *FieldPackerName = "fp";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001116 startFunction(AM_PublicSynchronized, false, "void", "set_" + VarName, 1,
1117 TypeName.c_str(), "v");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001118 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
Zonr Chang92b344a2010-10-05 20:39:03 +08001119
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001120 if (genCreateFieldPacker(ET, FieldPackerName))
1121 genPackVarOfType(ET, "v", FieldPackerName);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001122 mOut.indent() << "setVar(" RS_EXPORT_VAR_INDEX_PREFIX << VarName << ", "
1123 << FieldPackerName << ");\n";
Zonr Chang92b344a2010-10-05 20:39:03 +08001124
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001125 endFunction();
Zonr Chang92b344a2010-10-05 20:39:03 +08001126 }
1127
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001128 genGetExportVariable(TypeName, VarName);
1129 genGetFieldID(VarName);
Zonr Chang92b344a2010-10-05 20:39:03 +08001130}
1131
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001132void
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001133RSReflectionJava::genConstantArrayTypeExportVariable(const RSExportVar *EV) {
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001134 slangAssert(
1135 (EV->getType()->getClass() == RSExportType::ExportClassConstantArray) &&
1136 "Variable should be type of constant array here");
Zonr Chang2e1dba62010-10-05 22:20:11 +08001137
Stephen Hines0d26cef2012-05-01 19:23:01 -07001138 std::string TypeName = GetTypeName(EV->getType());
1139 std::string VarName = EV->getName();
Zonr Chang2e1dba62010-10-05 22:20:11 +08001140
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001141 genPrivateExportVariable(TypeName, VarName);
1142 genSetExportVariable(TypeName, EV);
1143 genGetExportVariable(TypeName, VarName);
1144 genGetFieldID(VarName);
Zonr Chang2e1dba62010-10-05 22:20:11 +08001145}
1146
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001147void RSReflectionJava::genRecordTypeExportVariable(const RSExportVar *EV) {
Stephen Hines6e6578a2011-02-07 18:05:48 -08001148 slangAssert((EV->getType()->getClass() == RSExportType::ExportClassRecord) &&
1149 "Variable should be type of struct here");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001150
Stephen Hines0d26cef2012-05-01 19:23:01 -07001151 std::string TypeName = GetTypeName(EV->getType());
1152 std::string VarName = EV->getName();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001153
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001154 genPrivateExportVariable(TypeName, VarName);
1155 genSetExportVariable(TypeName, EV);
1156 genGetExportVariable(TypeName, VarName);
1157 genGetFieldID(VarName);
Stephen Hines0d26cef2012-05-01 19:23:01 -07001158}
1159
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001160void RSReflectionJava::genPrivateExportVariable(const std::string &TypeName,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001161 const std::string &VarName) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001162 mOut.indent() << "private " << TypeName << " " << RS_EXPORT_VAR_PREFIX
1163 << VarName << ";\n";
Stephen Hines0d26cef2012-05-01 19:23:01 -07001164}
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001165
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001166void RSReflectionJava::genSetExportVariable(const std::string &TypeName,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001167 const RSExportVar *EV) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001168 if (!EV->isConst()) {
Stephen Hines0d26cef2012-05-01 19:23:01 -07001169 const char *FieldPackerName = "fp";
1170 std::string VarName = EV->getName();
1171 const RSExportType *ET = EV->getType();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001172 startFunction(AM_PublicSynchronized, false, "void", "set_" + VarName, 1,
1173 TypeName.c_str(), "v");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001174 mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001175
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001176 if (genCreateFieldPacker(ET, FieldPackerName))
1177 genPackVarOfType(ET, "v", FieldPackerName);
Stephen Hinesa6b54142012-04-09 18:25:08 -07001178
1179 if (mRSContext->getTargetAPI() < SLANG_JB_TARGET_API) {
1180 // Legacy apps must use the old setVar() without Element/dim components.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001181 mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
1182 << ", " << FieldPackerName << ");\n";
Stephen Hinesa6b54142012-04-09 18:25:08 -07001183 } else {
1184 // We only have support for one-dimensional array reflection today,
1185 // but the entry point (i.e. setVar()) takes an array of dimensions.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001186 mOut.indent() << "int []__dimArr = new int[1];\n";
1187 mOut.indent() << "__dimArr[0] = " << ET->getSize() << ";\n";
1188 mOut.indent() << "setVar(" << RS_EXPORT_VAR_INDEX_PREFIX << VarName
1189 << ", " << FieldPackerName << ", " << RS_ELEM_PREFIX
1190 << ET->getElementName() << ", __dimArr);\n";
Stephen Hinesa6b54142012-04-09 18:25:08 -07001191 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001192
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001193 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001194 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001195}
1196
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001197void RSReflectionJava::genGetExportVariable(const std::string &TypeName,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001198 const std::string &VarName) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001199 startFunction(AM_Public, false, TypeName.c_str(), "get_" + VarName, 0);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001200
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001201 mOut.indent() << "return " << RS_EXPORT_VAR_PREFIX << VarName << ";\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001202
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001203 endFunction();
Stephen Hines28d60bc2012-10-15 15:54:16 -07001204}
1205
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001206void RSReflectionJava::genGetFieldID(const std::string &VarName) {
Stephen Hines28d60bc2012-10-15 15:54:16 -07001207 // We only generate getFieldID_*() for non-Pointer (bind) types.
Tim Murrayb81a9932012-10-10 15:56:02 -07001208 if (mRSContext->getTargetAPI() >= SLANG_JB_MR1_TARGET_API) {
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001209 startFunction(AM_Public, false, "Script.FieldID", "getFieldID_" + VarName,
1210 0);
Tim Murrayb81a9932012-10-10 15:56:02 -07001211
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001212 mOut.indent() << "return createFieldID(" << RS_EXPORT_VAR_INDEX_PREFIX
1213 << VarName << ", null);\n";
Tim Murrayb81a9932012-10-10 15:56:02 -07001214
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001215 endFunction();
Tim Murrayb81a9932012-10-10 15:56:02 -07001216 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001217}
1218
1219/******************* Methods to generate script class /end *******************/
1220
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001221bool RSReflectionJava::genCreateFieldPacker(const RSExportType *ET,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001222 const char *FieldPackerName) {
Jean-Luc Brouilletc95381a2014-05-14 21:24:45 -07001223 size_t AllocSize = ET->getAllocSize();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001224 if (AllocSize > 0)
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001225 mOut.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker("
1226 << AllocSize << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001227 else
1228 return false;
1229 return true;
1230}
1231
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001232void RSReflectionJava::genPackVarOfType(const RSExportType *ET,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001233 const char *VarName,
1234 const char *FieldPackerName) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001235 switch (ET->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001236 case RSExportType::ExportClassPrimitive:
1237 case RSExportType::ExportClassVector: {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001238 mOut.indent() << FieldPackerName << "."
1239 << GetPackerAPIName(
1240 static_cast<const RSExportPrimitiveType *>(ET)) << "("
1241 << VarName << ");\n";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001242 break;
1243 }
1244 case RSExportType::ExportClassPointer: {
1245 // Must reflect as type Allocation in Java
1246 const RSExportType *PointeeType =
1247 static_cast<const RSExportPointerType *>(ET)->getPointeeType();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001248
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001249 if (PointeeType->getClass() != RSExportType::ExportClassRecord) {
1250 mOut.indent() << FieldPackerName << ".addI32(" << VarName
1251 << ".getPtr());\n";
1252 } else {
1253 mOut.indent() << FieldPackerName << ".addI32(" << VarName
1254 << ".getAllocation().getPtr());\n";
1255 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001256 break;
1257 }
1258 case RSExportType::ExportClassMatrix: {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001259 mOut.indent() << FieldPackerName << ".addMatrix(" << VarName << ");\n";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001260 break;
1261 }
1262 case RSExportType::ExportClassConstantArray: {
1263 const RSExportConstantArrayType *ECAT =
1264 static_cast<const RSExportConstantArrayType *>(ET);
1265
1266 // TODO(zonr): more elegant way. Currently, we obtain the unique index
1267 // variable (this method involves recursive call which means
1268 // we may have more than one level loop, therefore we can't
1269 // always use the same index variable name here) name given
1270 // in the for-loop from counting the '.' in @VarName.
1271 unsigned Level = 0;
1272 size_t LastDotPos = 0;
1273 std::string ElementVarName(VarName);
1274
1275 while (LastDotPos != std::string::npos) {
1276 LastDotPos = ElementVarName.find_first_of('.', LastDotPos + 1);
1277 Level++;
1278 }
1279 std::string IndexVarName("ct");
1280 IndexVarName.append(llvm::utostr_32(Level));
1281
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001282 mOut.indent() << "for (int " << IndexVarName << " = 0; " << IndexVarName
1283 << " < " << ECAT->getSize() << "; " << IndexVarName << "++)";
1284 mOut.startBlock();
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001285
1286 ElementVarName.append("[" + IndexVarName + "]");
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001287 genPackVarOfType(ECAT->getElementType(), ElementVarName.c_str(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001288 FieldPackerName);
1289
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001290 mOut.endBlock();
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001291 break;
1292 }
1293 case RSExportType::ExportClassRecord: {
1294 const RSExportRecordType *ERT = static_cast<const RSExportRecordType *>(ET);
1295 // Relative pos from now on in field packer
1296 unsigned Pos = 0;
1297
1298 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
1299 E = ERT->fields_end();
1300 I != E; I++) {
1301 const RSExportRecordType::Field *F = *I;
1302 std::string FieldName;
1303 size_t FieldOffset = F->getOffsetInParent();
1304 const RSExportType *T = F->getType();
1305 size_t FieldStoreSize = T->getStoreSize();
1306 size_t FieldAllocSize = T->getAllocSize();
1307
Chris Wailes5abbe0e2014-08-12 15:58:29 -07001308 if (VarName != nullptr)
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001309 FieldName = VarName + ("." + F->getName());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001310 else
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001311 FieldName = F->getName();
Zonr Chang89273bd2010-10-14 20:57:38 +08001312
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001313 if (FieldOffset > Pos) {
1314 mOut.indent() << FieldPackerName << ".skip(" << (FieldOffset - Pos)
1315 << ");\n";
1316 }
Zonr Chang89273bd2010-10-14 20:57:38 +08001317
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001318 genPackVarOfType(F->getType(), FieldName.c_str(), FieldPackerName);
Zonr Chang89273bd2010-10-14 20:57:38 +08001319
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001320 // There is padding in the field type
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001321 if (FieldAllocSize > FieldStoreSize) {
1322 mOut.indent() << FieldPackerName << ".skip("
1323 << (FieldAllocSize - FieldStoreSize) << ");\n";
1324 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001325
1326 Pos = FieldOffset + FieldAllocSize;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001327 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001328
1329 // There maybe some padding after the struct
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001330 if (ERT->getAllocSize() > Pos) {
1331 mOut.indent() << FieldPackerName << ".skip(" << ERT->getAllocSize() - Pos
1332 << ");\n";
1333 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001334 break;
1335 }
1336 default: { slangAssert(false && "Unknown class of type"); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001337 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001338}
1339
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001340void RSReflectionJava::genAllocateVarOfType(const RSExportType *T,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001341 const std::string &VarName) {
Zonr Chang2e1dba62010-10-05 22:20:11 +08001342 switch (T->getClass()) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001343 case RSExportType::ExportClassPrimitive: {
1344 // Primitive type like int in Java has its own storage once it's declared.
1345 //
1346 // FIXME: Should we allocate storage for RS object?
1347 // if (static_cast<const RSExportPrimitiveType *>(T)->isRSObjectType())
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001348 // mOut.indent() << VarName << " = new " << GetTypeName(T) << "();\n";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001349 break;
1350 }
1351 case RSExportType::ExportClassPointer: {
1352 // Pointer type is an instance of Allocation or a TypeClass whose value is
1353 // expected to be assigned by programmer later in Java program. Therefore
1354 // we don't reflect things like [VarName] = new Allocation();
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001355 mOut.indent() << VarName << " = null;\n";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001356 break;
1357 }
1358 case RSExportType::ExportClassConstantArray: {
1359 const RSExportConstantArrayType *ECAT =
1360 static_cast<const RSExportConstantArrayType *>(T);
1361 const RSExportType *ElementType = ECAT->getElementType();
Zonr Chang2e1dba62010-10-05 22:20:11 +08001362
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001363 mOut.indent() << VarName << " = new " << GetTypeName(ElementType) << "["
1364 << ECAT->getSize() << "];\n";
Zonr Chang2f1451c2010-10-14 02:58:28 +08001365
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001366 // Primitive type element doesn't need allocation code.
1367 if (ElementType->getClass() != RSExportType::ExportClassPrimitive) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001368 mOut.indent() << "for (int $ct = 0; $ct < " << ECAT->getSize()
1369 << "; $ct++)";
1370 mOut.startBlock();
Zonr Chang2e1dba62010-10-05 22:20:11 +08001371
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001372 std::string ElementVarName(VarName);
1373 ElementVarName.append("[$ct]");
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001374 genAllocateVarOfType(ElementType, ElementVarName);
Zonr Chang2e1dba62010-10-05 22:20:11 +08001375
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001376 mOut.endBlock();
Zonr Chang2e1dba62010-10-05 22:20:11 +08001377 }
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001378 break;
1379 }
1380 case RSExportType::ExportClassVector:
1381 case RSExportType::ExportClassMatrix:
1382 case RSExportType::ExportClassRecord: {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001383 mOut.indent() << VarName << " = new " << GetTypeName(T) << "();\n";
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001384 break;
1385 }
Zonr Chang2e1dba62010-10-05 22:20:11 +08001386 }
Zonr Chang2e1dba62010-10-05 22:20:11 +08001387}
1388
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001389void RSReflectionJava::genNewItemBufferIfNull(const char *Index) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001390 mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME " == null) ";
1391 mOut << RS_TYPE_ITEM_BUFFER_NAME << " = new " << RS_TYPE_ITEM_CLASS_NAME
1392 << "[getType().getX() /* count */];\n";
Chris Wailes5abbe0e2014-08-12 15:58:29 -07001393 if (Index != nullptr) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001394 mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME << "[" << Index
1395 << "] == null) ";
1396 mOut << RS_TYPE_ITEM_BUFFER_NAME << "[" << Index << "] = new "
1397 << RS_TYPE_ITEM_CLASS_NAME << "();\n";
1398 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001399}
1400
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001401void RSReflectionJava::genNewItemBufferPackerIfNull() {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001402 mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " == null) ";
1403 mOut << RS_TYPE_ITEM_BUFFER_PACKER_NAME " = new FieldPacker("
Tim Murray3a38b742014-07-02 10:41:08 -07001404 << mItemSizeof << " * getType().getX()/* count */);\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001405}
1406
1407/********************** Methods to generate type class **********************/
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001408bool RSReflectionJava::genTypeClass(const RSExportRecordType *ERT,
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001409 std::string &ErrorMsg) {
Stephen Hinesa6b54142012-04-09 18:25:08 -07001410 std::string ClassName = ERT->getElementName();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001411 std::string superClassName = getRSPackageName();
Tim Murrayf69e1e52013-01-17 13:57:24 -08001412 superClassName += RS_TYPE_CLASS_SUPER_CLASS_NAME;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001413
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001414 if (!startClass(AM_Public, false, ClassName, superClassName.c_str(),
1415 ErrorMsg))
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001416 return false;
1417
Stephen Hines4cc67fc2011-01-31 16:48:57 -08001418 mGeneratedFileNames->push_back(ClassName);
1419
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001420 genTypeItemClass(ERT);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001421
1422 // Declare item buffer and item buffer packer
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001423 mOut.indent() << "private " << RS_TYPE_ITEM_CLASS_NAME << " "
1424 << RS_TYPE_ITEM_BUFFER_NAME << "[];\n";
1425 mOut.indent() << "private FieldPacker " << RS_TYPE_ITEM_BUFFER_PACKER_NAME
1426 << ";\n";
1427 mOut.indent() << "private static java.lang.ref.WeakReference<Element> "
1428 << RS_TYPE_ELEMENT_REF_NAME
1429 << " = new java.lang.ref.WeakReference<Element>(null);\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001430
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001431 genTypeClassConstructor(ERT);
1432 genTypeClassCopyToArrayLocal(ERT);
1433 genTypeClassCopyToArray(ERT);
1434 genTypeClassItemSetter(ERT);
1435 genTypeClassItemGetter(ERT);
1436 genTypeClassComponentSetter(ERT);
1437 genTypeClassComponentGetter(ERT);
1438 genTypeClassCopyAll(ERT);
Stephen Hines82754d82013-01-18 19:46:06 -08001439 if (!mRSContext->isCompatLib()) {
1440 // Skip the resize method if we are targeting a compatibility library.
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001441 genTypeClassResize();
Stephen Hines82754d82013-01-18 19:46:06 -08001442 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001443
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001444 endClass();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001445
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001446 resetFieldIndex();
1447 clearFieldIndexMap();
Zonr Chang66aa2992010-10-05 15:56:31 +08001448
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001449 return true;
1450}
1451
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001452void RSReflectionJava::genTypeItemClass(const RSExportRecordType *ERT) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001453 mOut.indent() << "static public class " RS_TYPE_ITEM_CLASS_NAME;
1454 mOut.startBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001455
Tim Murray3a38b742014-07-02 10:41:08 -07001456 // Sizeof should not be exposed for 64-bit; it is not accurate
1457 if (mRSContext->getTargetAPI() < 21) {
1458 mOut.indent() << "public static final int sizeof = " << ERT->getAllocSize()
1459 << ";\n";
1460 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001461
1462 // Member elements
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001463 mOut << "\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001464 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001465 FE = ERT->fields_end();
1466 FI != FE; FI++) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001467 mOut.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName()
1468 << ";\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001469 }
1470
1471 // Constructor
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001472 mOut << "\n";
1473 mOut.indent() << RS_TYPE_ITEM_CLASS_NAME << "()";
1474 mOut.startBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001475
1476 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001477 FE = ERT->fields_end();
1478 FI != FE; FI++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001479 const RSExportRecordType::Field *F = *FI;
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001480 genAllocateVarOfType(F->getType(), F->getName());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001481 }
1482
1483 // end Constructor
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001484 mOut.endBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001485
1486 // end Item class
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001487 mOut.endBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001488}
1489
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001490void RSReflectionJava::genTypeClassConstructor(const RSExportRecordType *ERT) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001491 const char *RenderScriptVar = "rs";
1492
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001493 startFunction(AM_Public, true, "Element", "createElement", 1, "RenderScript",
1494 RenderScriptVar);
Jason Sams381e95f2011-11-30 14:01:43 -08001495
Stephen Hinese67239d2012-02-24 15:08:36 -08001496 // TODO(all): Fix weak-refs + multi-context issue.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001497 // mOut.indent() << "Element e = " << RS_TYPE_ELEMENT_REF_NAME
Jean-Luc Brouillet29689212014-05-27 13:25:31 -07001498 // << ".get();\n";
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001499 // mOut.indent() << "if (e != null) return e;\n";
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001500 RSReflectionJavaElementBuilder builder("eb", ERT, RenderScriptVar, &mOut,
1501 mRSContext, this);
1502 builder.generate();
1503
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001504 mOut.indent() << "return eb.create();\n";
1505 // mOut.indent() << "e = eb.create();\n";
1506 // mOut.indent() << RS_TYPE_ELEMENT_REF_NAME
Jean-Luc Brouillet29689212014-05-27 13:25:31 -07001507 // << " = new java.lang.ref.WeakReference<Element>(e);\n";
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001508 // mOut.indent() << "return e;\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001509 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001510
Jason Sams381e95f2011-11-30 14:01:43 -08001511 // private with element
Chris Wailes5abbe0e2014-08-12 15:58:29 -07001512 startFunction(AM_Private, false, nullptr, getClassName(), 1, "RenderScript",
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001513 RenderScriptVar);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001514 mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
1515 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
1516 mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001517 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001518
1519 // 1D without usage
Chris Wailes5abbe0e2014-08-12 15:58:29 -07001520 startFunction(AM_Public, false, nullptr, getClassName(), 2, "RenderScript",
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001521 RenderScriptVar, "int", "count");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001522
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001523 mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
1524 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
1525 mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001526 // Call init() in super class
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001527 mOut.indent() << "init(" << RenderScriptVar << ", count);\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001528 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001529
Jason Sams381e95f2011-11-30 14:01:43 -08001530 // 1D with usage
Chris Wailes5abbe0e2014-08-12 15:58:29 -07001531 startFunction(AM_Public, false, nullptr, getClassName(), 3, "RenderScript",
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001532 RenderScriptVar, "int", "count", "int", "usages");
Jason Sams91fe83b2010-12-06 17:07:12 -08001533
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001534 mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
1535 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
1536 mOut.indent() << "mElement = createElement(" << RenderScriptVar << ");\n";
Jason Sams91fe83b2010-12-06 17:07:12 -08001537 // Call init() in super class
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001538 mOut.indent() << "init(" << RenderScriptVar << ", count, usages);\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001539 endFunction();
Jason Sams91fe83b2010-12-06 17:07:12 -08001540
Jason Sams381e95f2011-11-30 14:01:43 -08001541 // create1D with usage
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001542 startFunction(AM_Public, true, getClassName().c_str(), "create1D", 3,
1543 "RenderScript", RenderScriptVar, "int", "dimX", "int",
1544 "usages");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001545 mOut.indent() << getClassName() << " obj = new " << getClassName() << "("
1546 << RenderScriptVar << ");\n";
1547 mOut.indent() << "obj.mAllocation = Allocation.createSized("
1548 "rs, obj.mElement, dimX, usages);\n";
1549 mOut.indent() << "return obj;\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001550 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001551
1552 // create1D without usage
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001553 startFunction(AM_Public, true, getClassName().c_str(), "create1D", 2,
1554 "RenderScript", RenderScriptVar, "int", "dimX");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001555 mOut.indent() << "return create1D(" << RenderScriptVar
1556 << ", dimX, Allocation.USAGE_SCRIPT);\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001557 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001558
Jason Sams381e95f2011-11-30 14:01:43 -08001559 // create2D without usage
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001560 startFunction(AM_Public, true, getClassName().c_str(), "create2D", 3,
1561 "RenderScript", RenderScriptVar, "int", "dimX", "int", "dimY");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001562 mOut.indent() << "return create2D(" << RenderScriptVar
1563 << ", dimX, dimY, Allocation.USAGE_SCRIPT);\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001564 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001565
1566 // create2D with usage
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001567 startFunction(AM_Public, true, getClassName().c_str(), "create2D", 4,
1568 "RenderScript", RenderScriptVar, "int", "dimX", "int", "dimY",
1569 "int", "usages");
Jason Sams381e95f2011-11-30 14:01:43 -08001570
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001571 mOut.indent() << getClassName() << " obj = new " << getClassName() << "("
1572 << RenderScriptVar << ");\n";
1573 mOut.indent() << "Type.Builder b = new Type.Builder(rs, obj.mElement);\n";
1574 mOut.indent() << "b.setX(dimX);\n";
1575 mOut.indent() << "b.setY(dimY);\n";
1576 mOut.indent() << "Type t = b.create();\n";
1577 mOut.indent() << "obj.mAllocation = Allocation.createTyped(rs, t, usages);\n";
1578 mOut.indent() << "return obj;\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001579 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001580
Jason Sams381e95f2011-11-30 14:01:43 -08001581 // createTypeBuilder
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001582 startFunction(AM_Public, true, "Type.Builder", "createTypeBuilder", 1,
1583 "RenderScript", RenderScriptVar);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001584 mOut.indent() << "Element e = createElement(" << RenderScriptVar << ");\n";
1585 mOut.indent() << "return new Type.Builder(rs, e);\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001586 endFunction();
Jason Sams381e95f2011-11-30 14:01:43 -08001587
1588 // createCustom with usage
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001589 startFunction(AM_Public, true, getClassName().c_str(), "createCustom", 3,
1590 "RenderScript", RenderScriptVar, "Type.Builder", "tb", "int",
1591 "usages");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001592 mOut.indent() << getClassName() << " obj = new " << getClassName() << "("
1593 << RenderScriptVar << ");\n";
1594 mOut.indent() << "Type t = tb.create();\n";
1595 mOut.indent() << "if (t.getElement() != obj.mElement) {\n";
1596 mOut.indent() << " throw new RSIllegalArgumentException("
1597 "\"Type.Builder did not match expected element type.\");\n";
1598 mOut.indent() << "}\n";
1599 mOut.indent() << "obj.mAllocation = Allocation.createTyped(rs, t, usages);\n";
1600 mOut.indent() << "return obj;\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001601 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001602}
1603
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001604void RSReflectionJava::genTypeClassCopyToArray(const RSExportRecordType *ERT) {
1605 startFunction(AM_Private, false, "void", "copyToArray", 2,
1606 RS_TYPE_ITEM_CLASS_NAME, "i", "int", "index");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001607
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001608 genNewItemBufferPackerIfNull();
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001609 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << ".reset(index * "
Tim Murray3a38b742014-07-02 10:41:08 -07001610 << mItemSizeof << ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001611
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001612 mOut.indent() << "copyToArrayLocal(i, " RS_TYPE_ITEM_BUFFER_PACKER_NAME
1613 ");\n";
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001614
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001615 endFunction();
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001616}
1617
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001618void
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001619RSReflectionJava::genTypeClassCopyToArrayLocal(const RSExportRecordType *ERT) {
1620 startFunction(AM_Private, false, "void", "copyToArrayLocal", 2,
1621 RS_TYPE_ITEM_CLASS_NAME, "i", "FieldPacker", "fp");
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001622
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001623 genPackVarOfType(ERT, "i", "fp");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001624
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001625 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001626}
1627
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001628void RSReflectionJava::genTypeClassItemSetter(const RSExportRecordType *ERT) {
1629 startFunction(AM_PublicSynchronized, false, "void", "set", 3,
1630 RS_TYPE_ITEM_CLASS_NAME, "i", "int", "index", "boolean",
1631 "copyNow");
Chris Wailes5abbe0e2014-08-12 15:58:29 -07001632 genNewItemBufferIfNull(nullptr);
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001633 mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << "[index] = i;\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001634
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001635 mOut.indent() << "if (copyNow) ";
1636 mOut.startBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001637
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001638 mOut.indent() << "copyToArray(i, index);\n";
Tim Murray3a38b742014-07-02 10:41:08 -07001639 mOut.indent() << "FieldPacker fp = new FieldPacker(" << mItemSizeof << ");\n";
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001640 mOut.indent() << "copyToArrayLocal(i, fp);\n";
1641 mOut.indent() << "mAllocation.setFromFieldPacker(index, fp);\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001642
1643 // End of if (copyNow)
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001644 mOut.endBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001645
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001646 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001647}
1648
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001649void RSReflectionJava::genTypeClassItemGetter(const RSExportRecordType *ERT) {
1650 startFunction(AM_PublicSynchronized, false, RS_TYPE_ITEM_CLASS_NAME, "get", 1,
1651 "int", "index");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001652 mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME
1653 << " == null) return null;\n";
1654 mOut.indent() << "return " << RS_TYPE_ITEM_BUFFER_NAME << "[index];\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001655 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001656}
1657
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001658void
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001659RSReflectionJava::genTypeClassComponentSetter(const RSExportRecordType *ERT) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001660 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001661 FE = ERT->fields_end();
1662 FI != FE; FI++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001663 const RSExportRecordType::Field *F = *FI;
1664 size_t FieldOffset = F->getOffsetInParent();
Jean-Luc Brouilletc95381a2014-05-14 21:24:45 -07001665 size_t FieldStoreSize = F->getType()->getStoreSize();
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001666 unsigned FieldIndex = getFieldIndex(F);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001667
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001668 startFunction(AM_PublicSynchronized, false, "void", "set_" + F->getName(),
1669 3, "int", "index", GetTypeName(F->getType()).c_str(), "v",
1670 "boolean", "copyNow");
1671 genNewItemBufferPackerIfNull();
1672 genNewItemBufferIfNull("index");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001673 mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << "[index]." << F->getName()
1674 << " = v;\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001675
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001676 mOut.indent() << "if (copyNow) ";
1677 mOut.startBlock();
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -07001678
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001679 if (FieldOffset > 0) {
1680 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << ".reset(index * "
Tim Murray3a38b742014-07-02 10:41:08 -07001681 << mItemSizeof << " + " << FieldOffset
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001682 << ");\n";
1683 } else {
1684 mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << ".reset(index * "
Tim Murray3a38b742014-07-02 10:41:08 -07001685 << mItemSizeof << ");\n";
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001686 }
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001687 genPackVarOfType(F->getType(), "v", RS_TYPE_ITEM_BUFFER_PACKER_NAME);
1688
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001689 mOut.indent() << "FieldPacker fp = new FieldPacker(" << FieldStoreSize
1690 << ");\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001691 genPackVarOfType(F->getType(), "v", "fp");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001692 mOut.indent() << "mAllocation.setFromFieldPacker(index, " << FieldIndex
1693 << ", fp);\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001694
1695 // End of if (copyNow)
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001696 mOut.endBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001697
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001698 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001699 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001700}
1701
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001702void
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001703RSReflectionJava::genTypeClassComponentGetter(const RSExportRecordType *ERT) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001704 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001705 FE = ERT->fields_end();
1706 FI != FE; FI++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001707 const RSExportRecordType::Field *F = *FI;
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001708 startFunction(AM_PublicSynchronized, false,
1709 GetTypeName(F->getType()).c_str(), "get_" + F->getName(), 1,
1710 "int", "index");
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001711 mOut.indent() << "if (" RS_TYPE_ITEM_BUFFER_NAME << " == null) return "
1712 << GetTypeNullValue(F->getType()) << ";\n";
1713 mOut.indent() << "return " RS_TYPE_ITEM_BUFFER_NAME << "[index]."
1714 << F->getName() << ";\n";
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001715 endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001716 }
Shih-wei Liao9c631ff2010-09-17 11:57:29 -07001717}
1718
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001719void RSReflectionJava::genTypeClassCopyAll(const RSExportRecordType *ERT) {
1720 startFunction(AM_PublicSynchronized, false, "void", "copyAll", 0);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001721
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001722 mOut.indent() << "for (int ct = 0; ct < " << RS_TYPE_ITEM_BUFFER_NAME
1723 << ".length; ct++)"
1724 << " copyToArray(" << RS_TYPE_ITEM_BUFFER_NAME
1725 << "[ct], ct);\n";
1726 mOut.indent() << "mAllocation.setFromFieldPacker(0, "
1727 << RS_TYPE_ITEM_BUFFER_PACKER_NAME ");\n";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001728
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001729 endFunction();
Shih-wei Liao9c631ff2010-09-17 11:57:29 -07001730}
1731
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001732void RSReflectionJava::genTypeClassResize() {
1733 startFunction(AM_PublicSynchronized, false, "void", "resize", 1, "int",
1734 "newSize");
Zonr Changd42a4292010-10-17 02:38:43 +08001735
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001736 mOut.indent() << "if (mItemArray != null) ";
1737 mOut.startBlock();
1738 mOut.indent() << "int oldSize = mItemArray.length;\n";
1739 mOut.indent() << "int copySize = Math.min(oldSize, newSize);\n";
1740 mOut.indent() << "if (newSize == oldSize) return;\n";
1741 mOut.indent() << "Item ni[] = new Item[newSize];\n";
1742 mOut.indent() << "System.arraycopy(mItemArray, 0, ni, 0, copySize);\n";
1743 mOut.indent() << "mItemArray = ni;\n";
1744 mOut.endBlock();
1745 mOut.indent() << "mAllocation.resize(newSize);\n";
Zonr Changd42a4292010-10-17 02:38:43 +08001746
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07001747 mOut.indent() << "if (" RS_TYPE_ITEM_BUFFER_PACKER_NAME
1748 " != null) " RS_TYPE_ITEM_BUFFER_PACKER_NAME " = "
Tim Murray3a38b742014-07-02 10:41:08 -07001749 "new FieldPacker(" << mItemSizeof << " * getType().getX()/* count */);\n";
Jason Samscedffd92010-12-16 15:29:49 -08001750
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001751 endFunction();
Zonr Changd42a4292010-10-17 02:38:43 +08001752}
1753
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001754/******************** Methods to generate type class /end ********************/
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001755
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001756/********** Methods to create Element in Java of given record type ***********/
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001757
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001758RSReflectionJavaElementBuilder::RSReflectionJavaElementBuilder(
1759 const char *ElementBuilderName, const RSExportRecordType *ERT,
1760 const char *RenderScriptVar, GeneratedFile *Out, const RSContext *RSContext,
1761 RSReflectionJava *Reflection)
1762 : mElementBuilderName(ElementBuilderName), mERT(ERT),
1763 mRenderScriptVar(RenderScriptVar), mOut(Out), mPaddingFieldIndex(1),
1764 mRSContext(RSContext), mReflection(Reflection) {
1765 if (mRSContext->getTargetAPI() < SLANG_ICS_TARGET_API) {
1766 mPaddingPrefix = "#padding_";
1767 } else {
1768 mPaddingPrefix = "#rs_padding_";
1769 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001770}
1771
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001772void RSReflectionJavaElementBuilder::generate() {
1773 mOut->indent() << "Element.Builder " << mElementBuilderName
1774 << " = new Element.Builder(" << mRenderScriptVar << ");\n";
1775 genAddElement(mERT, "", /* ArraySize = */ 0);
1776}
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001777
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001778void RSReflectionJavaElementBuilder::genAddElement(const RSExportType *ET,
1779 const std::string &VarName,
1780 unsigned ArraySize) {
Stephen Hines47aca4e2012-03-08 20:07:28 -08001781 std::string ElementConstruct = GetBuiltinElementConstruct(ET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001782
Stephen Hines47aca4e2012-03-08 20:07:28 -08001783 if (ElementConstruct != "") {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001784 genAddStatementStart();
1785 *mOut << ElementConstruct << "(" << mRenderScriptVar << ")";
1786 genAddStatementEnd(VarName, ArraySize);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001787 } else {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001788
1789 switch (ET->getClass()) {
1790 case RSExportType::ExportClassPrimitive: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001791 const RSExportPrimitiveType *EPT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001792 static_cast<const RSExportPrimitiveType *>(ET);
Stephen Hines47aca4e2012-03-08 20:07:28 -08001793 const char *DataTypeName =
1794 RSExportPrimitiveType::getRSReflectionType(EPT)->rs_type;
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001795 genAddStatementStart();
1796 *mOut << "Element.createUser(" << mRenderScriptVar
1797 << ", Element.DataType." << DataTypeName << ")";
1798 genAddStatementEnd(VarName, ArraySize);
1799 break;
1800 }
1801 case RSExportType::ExportClassVector: {
1802 const RSExportVectorType *EVT =
1803 static_cast<const RSExportVectorType *>(ET);
1804 const char *DataTypeName =
1805 RSExportPrimitiveType::getRSReflectionType(EVT)->rs_type;
1806 genAddStatementStart();
1807 *mOut << "Element.createVector(" << mRenderScriptVar
1808 << ", Element.DataType." << DataTypeName << ", "
1809 << EVT->getNumElement() << ")";
1810 genAddStatementEnd(VarName, ArraySize);
1811 break;
1812 }
1813 case RSExportType::ExportClassPointer:
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001814 // Pointer type variable should be resolved in
1815 // GetBuiltinElementConstruct()
Stephen Hines6e6578a2011-02-07 18:05:48 -08001816 slangAssert(false && "??");
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001817 break;
1818 case RSExportType::ExportClassMatrix:
Zonr Chang92b344a2010-10-05 20:39:03 +08001819 // Matrix type variable should be resolved
1820 // in GetBuiltinElementConstruct()
Stephen Hines6e6578a2011-02-07 18:05:48 -08001821 slangAssert(false && "??");
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001822 break;
1823 case RSExportType::ExportClassConstantArray: {
Zonr Chang2e1dba62010-10-05 22:20:11 +08001824 const RSExportConstantArrayType *ECAT =
1825 static_cast<const RSExportConstantArrayType *>(ET);
Zonr Chang2e1dba62010-10-05 22:20:11 +08001826
Zonr Chang89273bd2010-10-14 20:57:38 +08001827 const RSExportType *ElementType = ECAT->getElementType();
1828 if (ElementType->getClass() != RSExportType::ExportClassRecord) {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001829 genAddElement(ECAT->getElementType(), VarName, ECAT->getSize());
Zonr Chang89273bd2010-10-14 20:57:38 +08001830 } else {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001831 std::string NewElementBuilderName(mElementBuilderName);
Zonr Chang89273bd2010-10-14 20:57:38 +08001832 NewElementBuilderName.append(1, '_');
Zonr Chang2e1dba62010-10-05 22:20:11 +08001833
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001834 RSReflectionJavaElementBuilder builder(
1835 NewElementBuilderName.c_str(),
1836 static_cast<const RSExportRecordType *>(ElementType),
1837 mRenderScriptVar, mOut, mRSContext, mReflection);
1838 builder.generate();
1839
Zonr Chang89273bd2010-10-14 20:57:38 +08001840 ArraySize = ECAT->getSize();
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001841 genAddStatementStart();
1842 *mOut << NewElementBuilderName << ".create()";
1843 genAddStatementEnd(VarName, ArraySize);
Zonr Chang89273bd2010-10-14 20:57:38 +08001844 }
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001845 break;
1846 }
1847 case RSExportType::ExportClassRecord: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001848 // Simalar to case of RSExportType::ExportClassRecord in genPackVarOfType.
1849 //
zonr6315f762010-10-05 15:35:14 +08001850 // TODO(zonr): Generalize these two function such that there's no
1851 // duplicated codes.
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001852 const RSExportRecordType *ERT =
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001853 static_cast<const RSExportRecordType *>(ET);
1854 int Pos = 0; // relative pos from now on
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001855
1856 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001857 E = ERT->fields_end();
1858 I != E; I++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001859 const RSExportRecordType::Field *F = *I;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001860 int FieldOffset = F->getOffsetInParent();
Jean-Luc Brouilletc95381a2014-05-14 21:24:45 -07001861 const RSExportType *T = F->getType();
1862 int FieldStoreSize = T->getStoreSize();
1863 int FieldAllocSize = T->getAllocSize();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001864
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001865 std::string FieldName;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001866 if (!VarName.empty())
1867 FieldName = VarName + "." + F->getName();
1868 else
1869 FieldName = F->getName();
1870
1871 // Alignment
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001872 genAddPadding(FieldOffset - Pos);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001873
1874 // eb.add(...)
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001875 mReflection->addFieldIndexMapping(F);
Zonr Chang89273bd2010-10-14 20:57:38 +08001876 if (F->getType()->getClass() != RSExportType::ExportClassRecord) {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001877 genAddElement(F->getType(), FieldName, 0);
Zonr Chang89273bd2010-10-14 20:57:38 +08001878 } else {
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001879 std::string NewElementBuilderName(mElementBuilderName);
Zonr Chang89273bd2010-10-14 20:57:38 +08001880 NewElementBuilderName.append(1, '_');
1881
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001882 RSReflectionJavaElementBuilder builder(
1883 NewElementBuilderName.c_str(),
1884 static_cast<const RSExportRecordType *>(F->getType()),
1885 mRenderScriptVar, mOut, mRSContext, mReflection);
1886 builder.generate();
Zonr Chang89273bd2010-10-14 20:57:38 +08001887
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001888 genAddStatementStart();
1889 *mOut << NewElementBuilderName << ".create()";
1890 genAddStatementEnd(FieldName, ArraySize);
Zonr Chang89273bd2010-10-14 20:57:38 +08001891 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001892
Stephen Hinesa9ae5ae2011-11-11 21:16:59 -08001893 if (mRSContext->getTargetAPI() < SLANG_ICS_TARGET_API) {
1894 // There is padding within the field type. This is only necessary
1895 // for HC-targeted APIs.
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001896 genAddPadding(FieldAllocSize - FieldStoreSize);
Stephen Hinesa9ae5ae2011-11-11 21:16:59 -08001897 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001898
1899 Pos = FieldOffset + FieldAllocSize;
1900 }
1901
1902 // There maybe some padding after the struct
Jean-Luc Brouilletc95381a2014-05-14 21:24:45 -07001903 size_t RecordAllocSize = ERT->getAllocSize();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001904
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001905 genAddPadding(RecordAllocSize - Pos);
1906 break;
1907 }
1908 default:
Stephen Hines6e6578a2011-02-07 18:05:48 -08001909 slangAssert(false && "Unknown class of type");
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001910 break;
Shih-wei Liaob1a28e72010-06-16 16:31:32 -07001911 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001912 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001913}
1914
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001915void RSReflectionJavaElementBuilder::genAddPadding(int PaddingSize) {
1916 while (PaddingSize > 0) {
1917 const std::string &VarName = createPaddingField();
1918 genAddStatementStart();
1919 if (PaddingSize >= 4) {
1920 *mOut << "Element.U32(" << mRenderScriptVar << ")";
1921 PaddingSize -= 4;
1922 } else if (PaddingSize >= 2) {
1923 *mOut << "Element.U16(" << mRenderScriptVar << ")";
1924 PaddingSize -= 2;
1925 } else if (PaddingSize >= 1) {
1926 *mOut << "Element.U8(" << mRenderScriptVar << ")";
1927 PaddingSize -= 1;
1928 }
1929 genAddStatementEnd(VarName, 0);
1930 }
1931}
1932
1933void RSReflectionJavaElementBuilder::genAddStatementStart() {
1934 mOut->indent() << mElementBuilderName << ".add(";
1935}
1936
Jean-Luc Brouillet602def72014-05-27 16:11:37 -07001937void
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001938RSReflectionJavaElementBuilder::genAddStatementEnd(const std::string &VarName,
1939 unsigned ArraySize) {
1940 *mOut << ", \"" << VarName << "\"";
1941 if (ArraySize > 0) {
1942 *mOut << ", " << ArraySize;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001943 }
Jean-Luc Brouilletc643ceb2014-06-05 10:17:23 -07001944 *mOut << ");\n";
1945 // TODO Review incFieldIndex. It's probably better to assign the numbers at
1946 // the start rather
1947 // than as we're generating the code.
1948 mReflection->incFieldIndex();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001949}
1950
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001951/******** Methods to create Element in Java of given record type /end ********/
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001952
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -07001953bool RSReflectionJava::reflect() {
1954 std::string ErrorMsg;
1955 if (!genScriptClass(mScriptClassName, ErrorMsg)) {
1956 std::cerr << "Failed to generate class " << mScriptClassName << " ("
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001957 << ErrorMsg << ")\n";
1958 return false;
1959 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001960
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -07001961 mGeneratedFileNames->push_back(mScriptClassName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001962
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001963 // class ScriptField_<TypeName>
1964 for (RSContext::const_export_type_iterator
1965 TI = mRSContext->export_types_begin(),
1966 TE = mRSContext->export_types_end();
1967 TI != TE; TI++) {
1968 const RSExportType *ET = TI->getValue();
1969
1970 if (ET->getClass() == RSExportType::ExportClassRecord) {
1971 const RSExportRecordType *ERT =
1972 static_cast<const RSExportRecordType *>(ET);
1973
1974 if (!ERT->isArtificial() && !genTypeClass(ERT, ErrorMsg)) {
1975 std::cerr << "Failed to generate type class for struct '"
1976 << ERT->getName() << "' (" << ErrorMsg << ")\n";
1977 return false;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001978 }
1979 }
1980 }
1981
1982 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001983}
1984
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07001985const char *RSReflectionJava::AccessModifierStr(AccessModifier AM) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001986 switch (AM) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07001987 case AM_Public:
1988 return "public";
1989 break;
1990 case AM_Protected:
1991 return "protected";
1992 break;
1993 case AM_Private:
1994 return "private";
1995 break;
1996 case AM_PublicSynchronized:
1997 return "public synchronized";
1998 break;
1999 default:
2000 return "";
2001 break;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002002 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002003}
2004
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002005bool RSReflectionJava::startClass(AccessModifier AM, bool IsStatic,
2006 const std::string &ClassName,
2007 const char *SuperClassName,
2008 std::string &ErrorMsg) {
Zonr Chang8c6d9b22010-10-07 18:01:19 +08002009 // Open file for class
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002010 std::string FileName = ClassName + ".java";
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -07002011 if (!mOut.startFile(mOutputDirectory, FileName, mRSSourceFileName,
Stephen Hinesfc4f78b2014-06-10 18:07:10 -07002012 mRSContext->getLicenseNote(), true,
2013 mRSContext->getVerbose())) {
Zonr Chang8c6d9b22010-10-07 18:01:19 +08002014 return false;
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002015 }
Ying Wang4e348442010-08-18 10:29:12 -07002016
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002017 // Package
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002018 if (!mPackageName.empty()) {
2019 mOut << "package " << mPackageName << ";\n";
2020 }
2021 mOut << "\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002022
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002023 // Imports
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002024 mOut << "import " << mRSPackageName << ".*;\n";
Stephen Hines44d495d2014-05-22 19:42:55 -07002025 if (getEmbedBitcodeInJava()) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002026 mOut << "import " << mPackageName << "."
Stephen Hines44d495d2014-05-22 19:42:55 -07002027 << RSSlangReflectUtils::JavaBitcodeClassNameFromRSFileName(
Jean-Luc Brouillet59f22c32014-06-04 14:53:48 -07002028 mRSSourceFileName.c_str()) << ";\n";
Stephen Hines44d495d2014-05-22 19:42:55 -07002029 } else {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002030 mOut << "import android.content.res.Resources;\n";
Stephen Hines44d495d2014-05-22 19:42:55 -07002031 }
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002032 mOut << "\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002033
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002034 // All reflected classes should be annotated as hidden, so that they won't
2035 // be exposed in SDK.
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002036 mOut << "/**\n";
2037 mOut << " * @hide\n";
2038 mOut << " */\n";
Ying Wang4e348442010-08-18 10:29:12 -07002039
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002040 mOut << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class "
2041 << ClassName;
Chris Wailes5abbe0e2014-08-12 15:58:29 -07002042 if (SuperClassName != nullptr)
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002043 mOut << " extends " << SuperClassName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002044
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002045 mOut.startBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002046
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002047 mClassName = ClassName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002048
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002049 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002050}
2051
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002052void RSReflectionJava::endClass() {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002053 mOut.endBlock();
2054 mOut.closeFile();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002055 clear();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002056}
2057
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002058void RSReflectionJava::startTypeClass(const std::string &ClassName) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002059 mOut.indent() << "public static class " << ClassName;
2060 mOut.startBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002061}
2062
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002063void RSReflectionJava::endTypeClass() { mOut.endBlock(); }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002064
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002065void RSReflectionJava::startFunction(AccessModifier AM, bool IsStatic,
2066 const char *ReturnType,
2067 const std::string &FunctionName, int Argc,
2068 ...) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002069 ArgTy Args;
2070 va_list vl;
2071 va_start(vl, Argc);
2072
zonr6315f762010-10-05 15:35:14 +08002073 for (int i = 0; i < Argc; i++) {
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07002074 const char *ArgType = va_arg(vl, const char *);
2075 const char *ArgName = va_arg(vl, const char *);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002076
zonr6315f762010-10-05 15:35:14 +08002077 Args.push_back(std::make_pair(ArgType, ArgName));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002078 }
2079 va_end(vl);
2080
2081 startFunction(AM, IsStatic, ReturnType, FunctionName, Args);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002082}
2083
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002084void RSReflectionJava::startFunction(AccessModifier AM, bool IsStatic,
2085 const char *ReturnType,
2086 const std::string &FunctionName,
2087 const ArgTy &Args) {
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002088 mOut.indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ")
2089 << ((ReturnType) ? ReturnType : "") << " " << FunctionName
2090 << "(";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002091
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002092 bool FirstArg = true;
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07002093 for (ArgTy::const_iterator I = Args.begin(), E = Args.end(); I != E; I++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002094 if (!FirstArg)
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002095 mOut << ", ";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002096 else
2097 FirstArg = false;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002098
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002099 mOut << I->first << " " << I->second;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002100 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002101
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002102 mOut << ")";
2103 mOut.startBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002104}
2105
Jean-Luc Brouilletf33e1562014-06-03 17:55:57 -07002106void RSReflectionJava::endFunction() { mOut.endBlock(); }
Stephen Hinese639eb52010-11-08 19:27:20 -08002107
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002108bool RSReflectionJava::addTypeNameForElement(const std::string &TypeName) {
Stephen Hines1f6c3312012-07-03 17:23:33 -07002109 if (mTypesToCheck.find(TypeName) == mTypesToCheck.end()) {
2110 mTypesToCheck.insert(TypeName);
2111 return true;
2112 } else {
2113 return false;
2114 }
2115}
2116
Jean-Luc Brouillet2e205d02014-06-02 21:06:52 -07002117bool RSReflectionJava::addTypeNameForFieldPacker(const std::string &TypeName) {
Stephen Hines1f6c3312012-07-03 17:23:33 -07002118 if (mFieldPackerTypes.find(TypeName) == mFieldPackerTypes.end()) {
2119 mFieldPackerTypes.insert(TypeName);
2120 return true;
2121 } else {
2122 return false;
2123 }
2124}
2125
Jean-Luc Brouillet2ce118e2014-05-27 17:41:22 -07002126} // namespace slang