blob: 392caf2da67544b4f5dea90c1e1debe95f4d2734 [file] [log] [blame]
Zonr Changc383a502010-10-12 01:52:08 +08001/*
Stephen Hines48b72bf2011-06-10 15:37:27 -07002 * Copyright 2010-2011, The Android Open Source Project
Zonr Changc383a502010-10-12 01:52:08 +08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
zonr6315f762010-10-05 15:35:14 +080017#include "slang_rs_reflection.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070018
Stephen Hinese639eb52010-11-08 19:27:20 -080019#include <sys/stat.h>
20
Shih-wei Liao462aefd2010-06-04 15:32:04 -070021#include <cstdarg>
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070022#include <cctype>
Stephen Hinese639eb52010-11-08 19:27:20 -080023
24#include <algorithm>
25#include <string>
26#include <utility>
Shih-wei Liao462aefd2010-06-04 15:32:04 -070027
zonr6315f762010-10-05 15:35:14 +080028#include "llvm/ADT/APFloat.h"
Zonr Chang89273bd2010-10-14 20:57:38 +080029#include "llvm/ADT/StringExtras.h"
zonr6315f762010-10-05 15:35:14 +080030
Raphael8d5a2f62011-02-08 00:15:05 -080031#include "os_sep.h"
zonr6315f762010-10-05 15:35:14 +080032#include "slang_rs_context.h"
33#include "slang_rs_export_var.h"
Stephen Hines593a8942011-05-10 15:29:50 -070034#include "slang_rs_export_foreach.h"
zonr6315f762010-10-05 15:35:14 +080035#include "slang_rs_export_func.h"
36#include "slang_rs_reflect_utils.h"
Stephen Hines4cc499d2011-08-24 19:06:17 -070037#include "slang_version.h"
Stephen Hinese639eb52010-11-08 19:27:20 -080038#include "slang_utils.h"
zonr6315f762010-10-05 15:35:14 +080039
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070040#define RS_SCRIPT_CLASS_NAME_PREFIX "ScriptC_"
41#define RS_SCRIPT_CLASS_SUPER_CLASS_NAME "ScriptC"
Shih-wei Liao8b1d0dd2010-07-15 18:56:55 -070042
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070043#define RS_TYPE_CLASS_NAME_PREFIX "ScriptField_"
44#define RS_TYPE_CLASS_SUPER_CLASS_NAME "android.renderscript.Script.FieldBase"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070045
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070046#define RS_TYPE_ITEM_CLASS_NAME "Item"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070047
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070048#define RS_TYPE_ITEM_BUFFER_NAME "mItemArray"
49#define RS_TYPE_ITEM_BUFFER_PACKER_NAME "mIOBuffer"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070050
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070051#define RS_EXPORT_VAR_INDEX_PREFIX "mExportVarIdx_"
52#define RS_EXPORT_VAR_PREFIX "mExportVar_"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070053
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070054#define RS_EXPORT_FUNC_INDEX_PREFIX "mExportFuncIdx_"
Stephen Hines593a8942011-05-10 15:29:50 -070055#define RS_EXPORT_FOREACH_INDEX_PREFIX "mExportForEachIdx_"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070056
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070057#define RS_EXPORT_VAR_ALLOCATION_PREFIX "mAlloction_"
58#define RS_EXPORT_VAR_DATA_STORAGE_PREFIX "mData_"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070059
Stephen Hinese639eb52010-11-08 19:27:20 -080060namespace slang {
Shih-wei Liao462aefd2010-06-04 15:32:04 -070061
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070062// Some utility function using internal in RSReflection
63static bool GetClassNameFromFileName(const std::string &FileName,
64 std::string &ClassName) {
65 ClassName.clear();
Shih-wei Liao462aefd2010-06-04 15:32:04 -070066
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070067 if (FileName.empty() || (FileName == "-"))
Shih-wei Liao462aefd2010-06-04 15:32:04 -070068 return true;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070069
70 ClassName =
71 RSSlangReflectUtils::JavaClassNameFromRSFileName(FileName.c_str());
72
73 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070074}
75
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070076static const char *GetPrimitiveTypeName(const RSExportPrimitiveType *EPT) {
77 static const char *PrimitiveTypeJavaNameMap[] = {
Shih-wei Liao91a37832010-10-03 19:11:51 -070078 "", // RSExportPrimitiveType::DataTypeFloat16
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070079 "float", // RSExportPrimitiveType::DataTypeFloat32
80 "double", // RSExportPrimitiveType::DataTypeFloat64
81 "byte", // RSExportPrimitiveType::DataTypeSigned8
82 "short", // RSExportPrimitiveType::DataTypeSigned16
83 "int", // RSExportPrimitiveType::DataTypeSigned32
84 "long", // RSExportPrimitiveType::DataTypeSigned64
85 "short", // RSExportPrimitiveType::DataTypeUnsigned8
86 "int", // RSExportPrimitiveType::DataTypeUnsigned16
87 "long", // RSExportPrimitiveType::DataTypeUnsigned32
88 "long", // RSExportPrimitiveType::DataTypeUnsigned64
Shih-wei Liao91a37832010-10-03 19:11:51 -070089 "boolean", // RSExportPrimitiveType::DataTypeBoolean
Shih-wei Liao462aefd2010-06-04 15:32:04 -070090
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070091 "int", // RSExportPrimitiveType::DataTypeUnsigned565
92 "int", // RSExportPrimitiveType::DataTypeUnsigned5551
93 "int", // RSExportPrimitiveType::DataTypeUnsigned4444
Shih-wei Liao462aefd2010-06-04 15:32:04 -070094
Zonr Chang92b344a2010-10-05 20:39:03 +080095 "", // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2
96 "", // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3
97 "", // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4
Shih-wei Liaodd35e492010-06-21 14:42:40 -070098
Zonr Chang92b344a2010-10-05 20:39:03 +080099 "Element", // RSExportPrimitiveType::DataTypeRSElement
100 "Type", // RSExportPrimitiveType::DataTypeRSType
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700101 "Allocation", // RSExportPrimitiveType::DataTypeRSAllocation
Zonr Chang92b344a2010-10-05 20:39:03 +0800102 "Sampler", // RSExportPrimitiveType::DataTypeRSSampler
103 "Script", // RSExportPrimitiveType::DataTypeRSScript
104 "Mesh", // RSExportPrimitiveType::DataTypeRSMesh
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700105 "ProgramFragment", // RSExportPrimitiveType::DataTypeRSProgramFragment
106 "ProgramVertex", // RSExportPrimitiveType::DataTypeRSProgramVertex
107 "ProgramRaster", // RSExportPrimitiveType::DataTypeRSProgramRaster
108 "ProgramStore", // RSExportPrimitiveType::DataTypeRSProgramStore
109 "Font", // RSExportPrimitiveType::DataTypeRSFont
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700110 };
111 unsigned TypeId = EPT->getType();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700112
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700113 if (TypeId < (sizeof(PrimitiveTypeJavaNameMap) / sizeof(const char*))) {
114 return PrimitiveTypeJavaNameMap[ EPT->getType() ];
115 }
116
Stephen Hines6e6578a2011-02-07 18:05:48 -0800117 slangAssert(false && "GetPrimitiveTypeName : Unknown primitive data type");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700118 return NULL;
119}
120
121static const char *GetVectorTypeName(const RSExportVectorType *EVT) {
122 static const char *VectorTypeJavaNameMap[][3] = {
Stephen Hines4f9e08b2011-06-17 20:04:43 -0700123 /* 0 */ { "Byte2", "Byte3", "Byte4" },
124 /* 1 */ { "Short2", "Short3", "Short4" },
125 /* 2 */ { "Int2", "Int3", "Int4" },
126 /* 3 */ { "Long2", "Long3", "Long4" },
127 /* 4 */ { "Float2", "Float3", "Float4" },
128 /* 5 */ { "Double2", "Double3", "Double4" }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700129 };
130
131 const char **BaseElement = NULL;
132
133 switch (EVT->getType()) {
Stephen Hines48b72bf2011-06-10 15:37:27 -0700134 case RSExportPrimitiveType::DataTypeSigned8: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700135 BaseElement = VectorTypeJavaNameMap[0];
136 break;
Shih-wei Liao1f0d88f2010-06-25 00:15:24 -0700137 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700138 case RSExportPrimitiveType::DataTypeSigned16:
139 case RSExportPrimitiveType::DataTypeUnsigned8: {
140 BaseElement = VectorTypeJavaNameMap[1];
141 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700142 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700143 case RSExportPrimitiveType::DataTypeSigned32:
144 case RSExportPrimitiveType::DataTypeUnsigned16: {
145 BaseElement = VectorTypeJavaNameMap[2];
146 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700147 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700148 case RSExportPrimitiveType::DataTypeSigned64:
Stephen Hinesa5d2c232010-10-11 16:10:02 -0700149 case RSExportPrimitiveType::DataTypeUnsigned64:
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700150 case RSExportPrimitiveType::DataTypeUnsigned32: {
151 BaseElement = VectorTypeJavaNameMap[3];
152 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700153 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700154 case RSExportPrimitiveType::DataTypeFloat32: {
155 BaseElement = VectorTypeJavaNameMap[4];
156 break;
157 }
Stephen Hines4f9e08b2011-06-17 20:04:43 -0700158 case RSExportPrimitiveType::DataTypeFloat64: {
159 BaseElement = VectorTypeJavaNameMap[5];
160 break;
161 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700162 default: {
Stephen Hines48b72bf2011-06-10 15:37:27 -0700163 slangAssert(false && "RSReflection::GetVectorTypeName : Unsupported "
Stephen Hines6e6578a2011-02-07 18:05:48 -0800164 "vector element data type");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700165 break;
166 }
167 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700168
Stephen Hines6e6578a2011-02-07 18:05:48 -0800169 slangAssert((EVT->getNumElement() > 1) &&
170 (EVT->getNumElement() <= 4) &&
Stephen Hines48b72bf2011-06-10 15:37:27 -0700171 "Number of elements in vector type is invalid");
172
173 return BaseElement[EVT->getNumElement() - 2];
174}
175
176static const char *GetVectorElementName(const RSExportVectorType *EVT) {
177 static const char *VectorElementNameMap[][3] = {
178 /* 0 */ { "U8_2", "U8_3", "U8_4" },
179 /* 1 */ { "I8_2", "I8_3", "I8_4" },
180 /* 2 */ { "U16_2", "U16_3", "U16_4" },
181 /* 3 */ { "I16_2", "I16_3", "I16_4" },
182 /* 4 */ { "U32_2", "U32_3", "U32_4" },
183 /* 5 */ { "I32_2", "I32_3", "I32_4" },
184 /* 6 */ { "U64_2", "U64_3", "U64_4" },
185 /* 7 */ { "I64_2", "I64_3", "I64_4" },
186 /* 8 */ { "F32_2", "F32_3", "F32_4" },
187 /* 9 */ { "F64_2", "F64_3", "F64_4" },
188 };
189
190 const char **BaseElement = NULL;
191
192 switch (EVT->getType()) {
193 case RSExportPrimitiveType::DataTypeUnsigned8: {
194 BaseElement = VectorElementNameMap[0];
195 break;
196 }
197 case RSExportPrimitiveType::DataTypeSigned8: {
198 BaseElement = VectorElementNameMap[1];
199 break;
200 }
201 case RSExportPrimitiveType::DataTypeUnsigned16: {
202 BaseElement = VectorElementNameMap[2];
203 break;
204 }
205 case RSExportPrimitiveType::DataTypeSigned16: {
206 BaseElement = VectorElementNameMap[3];
207 break;
208 }
209 case RSExportPrimitiveType::DataTypeUnsigned32: {
210 BaseElement = VectorElementNameMap[4];
211 break;
212 }
213 case RSExportPrimitiveType::DataTypeSigned32: {
214 BaseElement = VectorElementNameMap[5];
215 break;
216 }
217 case RSExportPrimitiveType::DataTypeUnsigned64: {
218 BaseElement = VectorElementNameMap[6];
219 break;
220 }
221 case RSExportPrimitiveType::DataTypeSigned64: {
222 BaseElement = VectorElementNameMap[7];
223 break;
224 }
225 case RSExportPrimitiveType::DataTypeFloat32: {
226 BaseElement = VectorElementNameMap[8];
227 break;
228 }
229 case RSExportPrimitiveType::DataTypeFloat64: {
230 BaseElement = VectorElementNameMap[9];
231 break;
232 }
233 default: {
234 slangAssert(false && "RSReflection::GetVectorElementName : Unsupported "
235 "vector element data type");
236 break;
237 }
238 }
239
240 slangAssert((EVT->getNumElement() > 1) &&
241 (EVT->getNumElement() <= 4) &&
242 "Number of elements in vector type is invalid");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700243
244 return BaseElement[EVT->getNumElement() - 2];
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700245}
246
Zonr Chang92b344a2010-10-05 20:39:03 +0800247static const char *GetMatrixTypeName(const RSExportMatrixType *EMT) {
248 static const char *MatrixTypeJavaNameMap[] = {
249 /* 2x2 */ "Matrix2f",
250 /* 3x3 */ "Matrix3f",
251 /* 4x4 */ "Matrix4f",
252 };
253 unsigned Dim = EMT->getDim();
254
255 if ((Dim - 2) < (sizeof(MatrixTypeJavaNameMap) / sizeof(const char*)))
256 return MatrixTypeJavaNameMap[ EMT->getDim() - 2 ];
257
Stephen Hines6e6578a2011-02-07 18:05:48 -0800258 slangAssert(false && "GetMatrixTypeName : Unsupported matrix dimension");
Zonr Chang92b344a2010-10-05 20:39:03 +0800259 return NULL;
260}
261
Stephen Hines6e6578a2011-02-07 18:05:48 -0800262static const char *GetVectorAccessor(unsigned Index) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700263 static const char *VectorAccessorMap[] = {
264 /* 0 */ "x",
265 /* 1 */ "y",
266 /* 2 */ "z",
267 /* 3 */ "w",
268 };
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700269
Stephen Hines6e6578a2011-02-07 18:05:48 -0800270 slangAssert((Index < (sizeof(VectorAccessorMap) / sizeof(const char*))) &&
271 "Out-of-bound index to access vector member");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700272
273 return VectorAccessorMap[Index];
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700274}
275
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700276static const char *GetPackerAPIName(const RSExportPrimitiveType *EPT) {
zonr6315f762010-10-05 15:35:14 +0800277 static const char *PrimitiveTypePackerAPINameMap[] = {
Shih-wei Liao91a37832010-10-03 19:11:51 -0700278 "", // RSExportPrimitiveType::DataTypeFloat16
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700279 "addF32", // RSExportPrimitiveType::DataTypeFloat32
280 "addF64", // RSExportPrimitiveType::DataTypeFloat64
281 "addI8", // RSExportPrimitiveType::DataTypeSigned8
282 "addI16", // RSExportPrimitiveType::DataTypeSigned16
283 "addI32", // RSExportPrimitiveType::DataTypeSigned32
284 "addI64", // RSExportPrimitiveType::DataTypeSigned64
285 "addU8", // RSExportPrimitiveType::DataTypeUnsigned8
286 "addU16", // RSExportPrimitiveType::DataTypeUnsigned16
287 "addU32", // RSExportPrimitiveType::DataTypeUnsigned32
288 "addU64", // RSExportPrimitiveType::DataTypeUnsigned64
Shih-wei Liao91a37832010-10-03 19:11:51 -0700289 "addBoolean", // RSExportPrimitiveType::DataTypeBoolean
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700290
291 "addU16", // RSExportPrimitiveType::DataTypeUnsigned565
292 "addU16", // RSExportPrimitiveType::DataTypeUnsigned5551
293 "addU16", // RSExportPrimitiveType::DataTypeUnsigned4444
294
Alex Sakhartchoukaa180e92010-12-17 13:26:07 -0800295 "addMatrix", // RSExportPrimitiveType::DataTypeRSMatrix2x2
296 "addMatrix", // RSExportPrimitiveType::DataTypeRSMatrix3x3
297 "addMatrix", // RSExportPrimitiveType::DataTypeRSMatrix4x4
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700298
299 "addObj", // RSExportPrimitiveType::DataTypeRSElement
300 "addObj", // RSExportPrimitiveType::DataTypeRSType
301 "addObj", // RSExportPrimitiveType::DataTypeRSAllocation
302 "addObj", // RSExportPrimitiveType::DataTypeRSSampler
303 "addObj", // RSExportPrimitiveType::DataTypeRSScript
304 "addObj", // RSExportPrimitiveType::DataTypeRSMesh
305 "addObj", // RSExportPrimitiveType::DataTypeRSProgramFragment
306 "addObj", // RSExportPrimitiveType::DataTypeRSProgramVertex
307 "addObj", // RSExportPrimitiveType::DataTypeRSProgramRaster
308 "addObj", // RSExportPrimitiveType::DataTypeRSProgramStore
309 "addObj", // RSExportPrimitiveType::DataTypeRSFont
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700310 };
311 unsigned TypeId = EPT->getType();
312
313 if (TypeId < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char*)))
314 return PrimitiveTypePackerAPINameMap[ EPT->getType() ];
315
Stephen Hines6e6578a2011-02-07 18:05:48 -0800316 slangAssert(false && "GetPackerAPIName : Unknown primitive data type");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700317 return NULL;
318}
319
320static std::string GetTypeName(const RSExportType *ET) {
321 switch (ET->getClass()) {
Zonr Chang2e1dba62010-10-05 22:20:11 +0800322 case RSExportType::ExportClassPrimitive: {
zonr6315f762010-10-05 15:35:14 +0800323 return GetPrimitiveTypeName(
324 static_cast<const RSExportPrimitiveType*>(ET));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700325 }
326 case RSExportType::ExportClassPointer: {
327 const RSExportType *PointeeType =
328 static_cast<const RSExportPointerType*>(ET)->getPointeeType();
329
330 if (PointeeType->getClass() != RSExportType::ExportClassRecord)
331 return "Allocation";
332 else
333 return RS_TYPE_CLASS_NAME_PREFIX + PointeeType->getName();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700334 }
335 case RSExportType::ExportClassVector: {
336 return GetVectorTypeName(static_cast<const RSExportVectorType*>(ET));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700337 }
Zonr Chang92b344a2010-10-05 20:39:03 +0800338 case RSExportType::ExportClassMatrix: {
339 return GetMatrixTypeName(static_cast<const RSExportMatrixType*>(ET));
Zonr Chang2e1dba62010-10-05 22:20:11 +0800340 }
341 case RSExportType::ExportClassConstantArray: {
342 const RSExportConstantArrayType* CAT =
343 static_cast<const RSExportConstantArrayType*>(ET);
344 std::string ElementTypeName = GetTypeName(CAT->getElementType());
345 ElementTypeName.append("[]");
346 return ElementTypeName;
Zonr Chang92b344a2010-10-05 20:39:03 +0800347 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700348 case RSExportType::ExportClassRecord: {
zonr6315f762010-10-05 15:35:14 +0800349 return RS_TYPE_CLASS_NAME_PREFIX + ET->getName() +
350 "."RS_TYPE_ITEM_CLASS_NAME;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700351 }
352 default: {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800353 slangAssert(false && "Unknown class of type");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700354 }
355 }
356
357 return "";
358}
359
Shih-wei Liaocf950c42010-10-06 03:44:40 -0700360static const char *GetTypeNullValue(const RSExportType *ET) {
361 switch (ET->getClass()) {
362 case RSExportType::ExportClassPrimitive: {
Zonr Chang1ab1a452010-10-06 18:28:30 +0800363 const RSExportPrimitiveType *EPT =
364 static_cast<const RSExportPrimitiveType*>(ET);
365 if (EPT->isRSObjectType())
Shih-wei Liaocf950c42010-10-06 03:44:40 -0700366 return "null";
Zonr Chang1ab1a452010-10-06 18:28:30 +0800367 else if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean)
368 return "false";
Shih-wei Liaocf950c42010-10-06 03:44:40 -0700369 else
370 return "0";
371 break;
372 }
373 case RSExportType::ExportClassPointer:
374 case RSExportType::ExportClassVector:
375 case RSExportType::ExportClassMatrix:
376 case RSExportType::ExportClassConstantArray:
377 case RSExportType::ExportClassRecord: {
378 return "null";
379 break;
380 }
381 default: {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800382 slangAssert(false && "Unknown class of type");
Shih-wei Liaocf950c42010-10-06 03:44:40 -0700383 }
384 }
385 return "";
386}
387
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700388static const char *GetBuiltinElementConstruct(const RSExportType *ET) {
Zonr Chang2e1dba62010-10-05 22:20:11 +0800389 if (ET->getClass() == RSExportType::ExportClassPrimitive) {
zonr6315f762010-10-05 15:35:14 +0800390 const RSExportPrimitiveType *EPT =
391 static_cast<const RSExportPrimitiveType*>(ET);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700392 if (EPT->getKind() == RSExportPrimitiveType::DataKindUser) {
393 static const char *PrimitiveBuiltinElementConstructMap[] = {
Zonr Chang89273bd2010-10-14 20:57:38 +0800394 NULL, // RSExportPrimitiveType::DataTypeFloat16
395 "Element.F32", // RSExportPrimitiveType::DataTypeFloat32
396 "Element.F64", // RSExportPrimitiveType::DataTypeFloat64
397 "Element.I8", // RSExportPrimitiveType::DataTypeSigned8
Stephen Hines4f9e08b2011-06-17 20:04:43 -0700398 "Element.I16", // RSExportPrimitiveType::DataTypeSigned16
Zonr Chang89273bd2010-10-14 20:57:38 +0800399 "Element.I32", // RSExportPrimitiveType::DataTypeSigned32
400 "Element.I64", // RSExportPrimitiveType::DataTypeSigned64
401 "Element.U8", // RSExportPrimitiveType::DataTypeUnsigned8
Stephen Hines4f9e08b2011-06-17 20:04:43 -0700402 "Element.U16", // RSExportPrimitiveType::DataTypeUnsigned16
Zonr Chang89273bd2010-10-14 20:57:38 +0800403 "Element.U32", // RSExportPrimitiveType::DataTypeUnsigned32
404 "Element.U64", // RSExportPrimitiveType::DataTypeUnsigned64
405 "Element.BOOLEAN", // RSExportPrimitiveType::DataTypeBoolean
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700406
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700407 NULL, // RSExportPrimitiveType::DataTypeUnsigned565
408 NULL, // RSExportPrimitiveType::DataTypeUnsigned5551
409 NULL, // RSExportPrimitiveType::DataTypeUnsigned4444
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700410
Zonr Chang92b344a2010-10-05 20:39:03 +0800411 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2
412 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3
413 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4
Shih-wei Liaodd35e492010-06-21 14:42:40 -0700414
Zonr Chang89273bd2010-10-14 20:57:38 +0800415 "Element.ELEMENT", // RSExportPrimitiveType::DataTypeRSElement
416 "Element.TYPE", // RSExportPrimitiveType::DataTypeRSType
417 "Element.ALLOCATION", // RSExportPrimitiveType::DataTypeRSAllocation
418 "Element.SAMPLER", // RSExportPrimitiveType::DataTypeRSSampler
419 "Element.SCRIPT", // RSExportPrimitiveType::DataTypeRSScript
420 "Element.MESH", // RSExportPrimitiveType::DataTypeRSMesh
Stephen Hinese639eb52010-11-08 19:27:20 -0800421 "Element.PROGRAM_FRAGMENT",
422 // RSExportPrimitiveType::DataTypeRSProgramFragment
423 "Element.PROGRAM_VERTEX",
424 // RSExportPrimitiveType::DataTypeRSProgramVertex
425 "Element.PROGRAM_RASTER",
426 // RSExportPrimitiveType::DataTypeRSProgramRaster
427 "Element.PROGRAM_STORE",
428 // RSExportPrimitiveType::DataTypeRSProgramStore
429 "Element.FONT",
430 // RSExportPrimitiveType::DataTypeRSFont
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700431 };
432 unsigned TypeId = EPT->getType();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700433
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700434 if (TypeId <
435 (sizeof(PrimitiveBuiltinElementConstructMap) / sizeof(const char*)))
436 return PrimitiveBuiltinElementConstructMap[ EPT->getType() ];
437 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelA) {
438 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
Zonr Chang89273bd2010-10-14 20:57:38 +0800439 return "Element.A_8";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700440 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGB) {
441 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned565)
Zonr Chang89273bd2010-10-14 20:57:38 +0800442 return "Element.RGB_565";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700443 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
Zonr Chang89273bd2010-10-14 20:57:38 +0800444 return "Element.RGB_888";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700445 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGBA) {
446 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned5551)
Zonr Chang89273bd2010-10-14 20:57:38 +0800447 return "Element.RGBA_5551";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700448 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned4444)
Zonr Chang89273bd2010-10-14 20:57:38 +0800449 return "Element.RGBA_4444";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700450 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
Zonr Chang89273bd2010-10-14 20:57:38 +0800451 return "Element.RGBA_8888";
Shih-wei Liao8b1d0dd2010-07-15 18:56:55 -0700452 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700453 } else if (ET->getClass() == RSExportType::ExportClassVector) {
454 const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(ET);
Shih-wei Liao91a37832010-10-03 19:11:51 -0700455 if (EVT->getKind() == RSExportPrimitiveType::DataKindUser) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700456 if (EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) {
457 if (EVT->getNumElement() == 2)
Zonr Chang89273bd2010-10-14 20:57:38 +0800458 return "Element.F32_2";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700459 else if (EVT->getNumElement() == 3)
Zonr Chang89273bd2010-10-14 20:57:38 +0800460 return "Element.F32_3";
Shih-wei Liao91a37832010-10-03 19:11:51 -0700461 else if (EVT->getNumElement() == 4)
Zonr Chang89273bd2010-10-14 20:57:38 +0800462 return "Element.F32_4";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700463 } else if (EVT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) {
464 if (EVT->getNumElement() == 4)
Zonr Chang89273bd2010-10-14 20:57:38 +0800465 return "Element.U8_4";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700466 }
Shih-wei Liao324c0472010-06-21 13:15:11 -0700467 }
Zonr Chang92b344a2010-10-05 20:39:03 +0800468 } else if (ET->getClass() == RSExportType::ExportClassMatrix) {
469 const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType *>(ET);
470 switch (EMT->getDim()) {
Zonr Chang89273bd2010-10-14 20:57:38 +0800471 case 2: return "Element.MATRIX_2X2";
472 case 3: return "Element.MATRIX_3X3";
473 case 4: return "Element.MATRIX_4X4";
Stephen Hines6e6578a2011-02-07 18:05:48 -0800474 default: slangAssert(false && "Unsupported dimension of matrix");
Zonr Chang92b344a2010-10-05 20:39:03 +0800475 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700476 } else if (ET->getClass() == RSExportType::ExportClassPointer) {
477 // Treat pointer type variable as unsigned int
zonr6315f762010-10-05 15:35:14 +0800478 // TODO(zonr): this is target dependent
Zonr Chang89273bd2010-10-14 20:57:38 +0800479 return "Element.USER_I32";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700480 }
Shih-wei Liao324c0472010-06-21 13:15:11 -0700481
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700482 return NULL;
Shih-wei Liao324c0472010-06-21 13:15:11 -0700483}
484
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700485static const char *GetElementDataKindName(RSExportPrimitiveType::DataKind DK) {
486 static const char *ElementDataKindNameMap[] = {
487 "Element.DataKind.USER", // RSExportPrimitiveType::DataKindUser
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700488 "Element.DataKind.PIXEL_L", // RSExportPrimitiveType::DataKindPixelL
489 "Element.DataKind.PIXEL_A", // RSExportPrimitiveType::DataKindPixelA
490 "Element.DataKind.PIXEL_LA", // RSExportPrimitiveType::DataKindPixelLA
491 "Element.DataKind.PIXEL_RGB", // RSExportPrimitiveType::DataKindPixelRGB
492 "Element.DataKind.PIXEL_RGBA", // RSExportPrimitiveType::DataKindPixelRGBA
493 };
Shih-wei Liao324c0472010-06-21 13:15:11 -0700494
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700495 if (static_cast<unsigned>(DK) <
496 (sizeof(ElementDataKindNameMap) / sizeof(const char*)))
497 return ElementDataKindNameMap[ DK ];
498 else
499 return NULL;
Shih-wei Liao324c0472010-06-21 13:15:11 -0700500}
501
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700502static const char *GetElementDataTypeName(RSExportPrimitiveType::DataType DT) {
503 static const char *ElementDataTypeNameMap[] = {
Stephen Hinese639eb52010-11-08 19:27:20 -0800504 NULL, // RSExportPrimitiveType::DataTypeFloat16
505 "Element.DataType.FLOAT_32", // RSExportPrimitiveType::DataTypeFloat32
506 "Element.DataType.FLOAT_64", // RSExportPrimitiveType::DataTypeFloat64
507 "Element.DataType.SIGNED_8", // RSExportPrimitiveType::DataTypeSigned8
508 "Element.DataType.SIGNED_16", // RSExportPrimitiveType::DataTypeSigned16
509 "Element.DataType.SIGNED_32", // RSExportPrimitiveType::DataTypeSigned32
510 "Element.DataType.SIGNED_64", // RSExportPrimitiveType::DataTypeSigned64
511 "Element.DataType.UNSIGNED_8", // RSExportPrimitiveType::DataTypeUnsigned8
512 "Element.DataType.UNSIGNED_16",
513 // RSExportPrimitiveType::DataTypeUnsigned16
514 "Element.DataType.UNSIGNED_32",
515 // RSExportPrimitiveType::DataTypeUnsigned32
516 "Element.DataType.UNSIGNED_64",
517 // RSExportPrimitiveType::DataTypeUnsigned64
518 "Element.DataType.BOOLEAN",
519 // RSExportPrimitiveType::DataTypeBoolean
Shih-wei Liao91a37832010-10-03 19:11:51 -0700520
521 // RSExportPrimitiveType::DataTypeUnsigned565
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700522 "Element.DataType.UNSIGNED_5_6_5",
Shih-wei Liao91a37832010-10-03 19:11:51 -0700523 // RSExportPrimitiveType::DataTypeUnsigned5551
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700524 "Element.DataType.UNSIGNED_5_5_5_1",
Shih-wei Liao91a37832010-10-03 19:11:51 -0700525 // RSExportPrimitiveType::DataTypeUnsigned4444
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700526 "Element.DataType.UNSIGNED_4_4_4_4",
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700527
Zonr Chang92b344a2010-10-05 20:39:03 +0800528 // DataTypeRSMatrix* must have been resolved in GetBuiltinElementConstruct()
Stephen Hinese639eb52010-11-08 19:27:20 -0800529 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2
530 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3
531 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700532
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700533 "Element.DataType.RS_ELEMENT", // RSExportPrimitiveType::DataTypeRSElement
534 "Element.DataType.RS_TYPE", // RSExportPrimitiveType::DataTypeRSType
535 // RSExportPrimitiveType::DataTypeRSAllocation
536 "Element.DataType.RS_ALLOCATION",
537 // RSExportPrimitiveType::DataTypeRSSampler
538 "Element.DataType.RS_SAMPLER",
539 // RSExportPrimitiveType::DataTypeRSScript
540 "Element.DataType.RS_SCRIPT",
541 // RSExportPrimitiveType::DataTypeRSMesh
542 "Element.DataType.RS_MESH",
543 // RSExportPrimitiveType::DataTypeRSProgramFragment
544 "Element.DataType.RS_PROGRAM_FRAGMENT",
545 // RSExportPrimitiveType::DataTypeRSProgramVertex
546 "Element.DataType.RS_PROGRAM_VERTEX",
547 // RSExportPrimitiveType::DataTypeRSProgramRaster
548 "Element.DataType.RS_PROGRAM_RASTER",
549 // RSExportPrimitiveType::DataTypeRSProgramStore
550 "Element.DataType.RS_PROGRAM_STORE",
551 // RSExportPrimitiveType::DataTypeRSFont
552 "Element.DataType.RS_FONT",
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700553 };
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700554
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700555 if (static_cast<unsigned>(DT) <
556 (sizeof(ElementDataTypeNameMap) / sizeof(const char*)))
557 return ElementDataTypeNameMap[ DT ];
558 else
559 return NULL;
560}
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700561
Stephen Hines48b72bf2011-06-10 15:37:27 -0700562static const char *GetElementJavaTypeName(RSExportPrimitiveType::DataType DT) {
563 static const char *ElementJavaTypeNameMap[] = {
Stephen Hinesecddee32011-07-20 18:30:09 -0700564 NULL, // RSExportPrimitiveType::DataTypeFloat16
565 "F32", // RSExportPrimitiveType::DataTypeFloat32
566 "F64", // RSExportPrimitiveType::DataTypeFloat64
567 "I8", // RSExportPrimitiveType::DataTypeSigned8
568 "I16", // RSExportPrimitiveType::DataTypeSigned16
569 "I32", // RSExportPrimitiveType::DataTypeSigned32
570 "I64", // RSExportPrimitiveType::DataTypeSigned64
571 "U8", // RSExportPrimitiveType::DataTypeUnsigned8
572 "U16", // RSExportPrimitiveType::DataTypeUnsigned16
573 "U32", // RSExportPrimitiveType::DataTypeUnsigned32
574 "U64", // RSExportPrimitiveType::DataTypeUnsigned64
575 "BOOLEAN", // RSExportPrimitiveType::DataTypeBoolean
Stephen Hines48b72bf2011-06-10 15:37:27 -0700576
Stephen Hinesecddee32011-07-20 18:30:09 -0700577 "RGB_565", // RSExportPrimitiveType::DataTypeUnsigned565
578 "RGBA_5551", // RSExportPrimitiveType::DataTypeUnsigned5551
579 "RGBA_4444", // RSExportPrimitiveType::DataTypeUnsigned4444
Stephen Hines48b72bf2011-06-10 15:37:27 -0700580
581 // DataTypeRSMatrix* must have been resolved in GetBuiltinElementConstruct()
Stephen Hinesecddee32011-07-20 18:30:09 -0700582 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2
583 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3
584 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4
Stephen Hines48b72bf2011-06-10 15:37:27 -0700585
Stephen Hinesecddee32011-07-20 18:30:09 -0700586 "ELEMENT", // RSExportPrimitiveType::DataTypeRSElement
587 "TYPE", // RSExportPrimitiveType::DataTypeRSType
588 "ALLOCATION", // RSExportPrimitiveType::DataTypeRSAllocation
589 "SAMPLER", // RSExportPrimitiveType::DataTypeRSSampler
590 "SCRIPT", // RSExportPrimitiveType::DataTypeRSScript
591 "MESH", // RSExportPrimitiveType::DataTypeRSMesh
592 "PROGRAM_FRAGMENT", // RSExportPrimitiveType::DataTypeRSProgramFragment
593 "PROGRAM_VERTEX", // RSExportPrimitiveType::DataTypeRSProgramVertex
594 "PROGRAM_RASTER", // RSExportPrimitiveType::DataTypeRSProgramRaster
595 "PROGRAM_STORE", // RSExportPrimitiveType::DataTypeRSProgramStore
596 "FONT", // RSExportPrimitiveType::DataTypeRSFont
Stephen Hines48b72bf2011-06-10 15:37:27 -0700597 };
598
599 if (static_cast<unsigned>(DT) <
600 (sizeof(ElementJavaTypeNameMap) / sizeof(const char*)))
601 return ElementJavaTypeNameMap[DT];
602 else
603 return NULL;
604}
605
606
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700607/********************** Methods to generate script class **********************/
608bool RSReflection::genScriptClass(Context &C,
609 const std::string &ClassName,
610 std::string &ErrorMsg) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700611 if (!C.startClass(Context::AM_Public,
612 false,
613 ClassName,
614 RS_SCRIPT_CLASS_SUPER_CLASS_NAME,
615 ErrorMsg))
616 return false;
617
618 genScriptClassConstructor(C);
619
620 // Reflect export variable
621 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
622 E = mRSContext->export_vars_end();
623 I != E;
624 I++)
625 genExportVariable(C, *I);
626
Stephen Hines4a4bf922011-08-18 17:20:33 -0700627 // Reflect export for each functions (only available on ICS+)
Stephen Hines4cc499d2011-08-24 19:06:17 -0700628 if (mRSContext->getTargetAPI() >= SLANG_ICS_TARGET_API) {
Stephen Hines4a4bf922011-08-18 17:20:33 -0700629 for (RSContext::const_export_foreach_iterator
630 I = mRSContext->export_foreach_begin(),
631 E = mRSContext->export_foreach_end();
632 I != E; I++)
633 genExportForEach(C, *I);
634 }
Stephen Hines593a8942011-05-10 15:29:50 -0700635
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700636 // Reflect export function
637 for (RSContext::const_export_func_iterator
638 I = mRSContext->export_funcs_begin(),
639 E = mRSContext->export_funcs_end();
640 I != E; I++)
641 genExportFunction(C, *I);
642
643 C.endClass();
644
645 return true;
646}
647
648void RSReflection::genScriptClassConstructor(Context &C) {
649 C.indent() << "// Constructor" << std::endl;
650 C.startFunction(Context::AM_Public,
651 false,
652 NULL,
653 C.getClassName(),
Jason Samsb6902e22010-11-03 17:04:06 -0700654 3,
Zonr Changd42a4292010-10-17 02:38:43 +0800655 "RenderScript", "rs",
656 "Resources", "resources",
Jason Samsb6902e22010-11-03 17:04:06 -0700657 "int", "id");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700658 // Call constructor of super class
Jason Samsb6902e22010-11-03 17:04:06 -0700659 C.indent() << "super(rs, resources, id);" << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700660
661 // If an exported variable has initial value, reflect it
662
663 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
664 E = mRSContext->export_vars_end();
665 I != E;
666 I++) {
667 const RSExportVar *EV = *I;
668 if (!EV->getInit().isUninit())
669 genInitExportVariable(C, EV->getType(), EV->getName(), EV->getInit());
670 }
671
Stephen Hines48b72bf2011-06-10 15:37:27 -0700672 for (RSContext::const_export_foreach_iterator
673 I = mRSContext->export_foreach_begin(),
674 E = mRSContext->export_foreach_end();
675 I != E;
676 I++) {
677 const RSExportForEach *EF = *I;
678
679 const RSExportType *IET = EF->getInType();
680 if (IET) {
681 genTypeInstance(C, IET);
682 }
683 const RSExportType *OET = EF->getOutType();
684 if (OET) {
685 genTypeInstance(C, OET);
686 }
687 }
688
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700689 C.endFunction();
Jason Samsb6902e22010-11-03 17:04:06 -0700690
Stephen Hines48b72bf2011-06-10 15:37:27 -0700691 for (std::set<std::string>::iterator I = C.mTypesToCheck.begin(),
692 E = C.mTypesToCheck.end();
693 I != E;
694 I++) {
695 C.indent() << "private Element __" << *I << ";" << std::endl;
696 }
697
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700698 return;
699}
700
701void RSReflection::genInitBoolExportVariable(Context &C,
702 const std::string &VarName,
703 const clang::APValue &Val) {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800704 slangAssert(!Val.isUninit() && "Not a valid initializer");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700705
706 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
Stephen Hines6e6578a2011-02-07 18:05:48 -0800707 slangAssert((Val.getKind() == clang::APValue::Int) &&
708 "Bool type has wrong initial APValue");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700709
Zonr Chang92b344a2010-10-05 20:39:03 +0800710 C.out() << ((Val.getInt().getSExtValue() == 0) ? "false" : "true")
711 << ";" << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700712
713 return;
714}
715
Stephen Hinese639eb52010-11-08 19:27:20 -0800716void RSReflection::genInitPrimitiveExportVariable(
717 Context &C,
718 const std::string &VarName,
719 const clang::APValue &Val) {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800720 slangAssert(!Val.isUninit() && "Not a valid initializer");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700721
722 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
723 switch (Val.getKind()) {
724 case clang::APValue::Int: {
Stephen Hines050eb852010-10-07 11:38:29 -0700725 llvm::APInt api = Val.getInt();
726 C.out() << api.getSExtValue();
727 if (api.getBitWidth() > 32) {
728 C.out() << "L";
729 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700730 break;
731 }
732 case clang::APValue::Float: {
733 llvm::APFloat apf = Val.getFloat();
734 if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) {
735 C.out() << apf.convertToFloat() << "f";
736 } else {
737 C.out() << apf.convertToDouble();
738 }
739 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700740 }
741
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700742 case clang::APValue::ComplexInt:
743 case clang::APValue::ComplexFloat:
744 case clang::APValue::LValue:
745 case clang::APValue::Vector: {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800746 slangAssert(false &&
747 "Primitive type cannot have such kind of initializer");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700748 break;
749 }
750 default: {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800751 slangAssert(false && "Unknown kind of initializer");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700752 }
753 }
754 C.out() << ";" << std::endl;
755
756 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700757}
758
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700759void RSReflection::genInitExportVariable(Context &C,
760 const RSExportType *ET,
761 const std::string &VarName,
762 const clang::APValue &Val) {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800763 slangAssert(!Val.isUninit() && "Not a valid initializer");
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700764
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700765 switch (ET->getClass()) {
Zonr Chang2e1dba62010-10-05 22:20:11 +0800766 case RSExportType::ExportClassPrimitive: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700767 const RSExportPrimitiveType *EPT =
768 static_cast<const RSExportPrimitiveType*>(ET);
Shih-wei Liao91a37832010-10-03 19:11:51 -0700769 if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700770 genInitBoolExportVariable(C, VarName, Val);
771 } else {
772 genInitPrimitiveExportVariable(C, VarName, Val);
773 }
774 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700775 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700776 case RSExportType::ExportClassPointer: {
777 if (!Val.isInt() || Val.getInt().getSExtValue() != 0)
778 std::cout << "Initializer which is non-NULL to pointer type variable "
779 "will be ignored" << std::endl;
780 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700781 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700782 case RSExportType::ExportClassVector: {
783 const RSExportVectorType *EVT =
784 static_cast<const RSExportVectorType*>(ET);
785 switch (Val.getKind()) {
786 case clang::APValue::Int:
787 case clang::APValue::Float: {
Zonr Chang2e1dba62010-10-05 22:20:11 +0800788 for (unsigned i = 0; i < EVT->getNumElement(); i++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700789 std::string Name = VarName + "." + GetVectorAccessor(i);
790 genInitPrimitiveExportVariable(C, Name, Val);
Shih-wei Liao1ebc0ca2010-09-14 10:57:21 -0700791 }
792 break;
793 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700794 case clang::APValue::Vector: {
795 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new "
796 << GetVectorTypeName(EVT) << "();" << std::endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700797
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700798 unsigned NumElements =
799 std::min(static_cast<unsigned>(EVT->getNumElement()),
800 Val.getVectorLength());
801 for (unsigned i = 0; i < NumElements; i++) {
802 const clang::APValue &ElementVal = Val.getVectorElt(i);
803 std::string Name = VarName + "." + GetVectorAccessor(i);
804 genInitPrimitiveExportVariable(C, Name, ElementVal);
805 }
806 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700807 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700808 case clang::APValue::Uninitialized:
809 case clang::APValue::ComplexInt:
810 case clang::APValue::ComplexFloat:
Stephen Hines4c622e02011-11-10 18:57:34 -0800811 case clang::APValue::LValue:
812 case clang::APValue::Array:
813 case clang::APValue::Struct:
814 case clang::APValue::Union: {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800815 slangAssert(false && "Unexpected type of value of initializer.");
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700816 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700817 }
818 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700819 }
Zonr Chang92b344a2010-10-05 20:39:03 +0800820 // TODO(zonr): Resolving initializer of a record (and matrix) type variable
821 // is complex. It cannot obtain by just simply evaluating the initializer
822 // expression.
823 case RSExportType::ExportClassMatrix:
Zonr Chang2e1dba62010-10-05 22:20:11 +0800824 case RSExportType::ExportClassConstantArray:
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700825 case RSExportType::ExportClassRecord: {
826#if 0
827 unsigned InitIndex = 0;
zonr6315f762010-10-05 15:35:14 +0800828 const RSExportRecordType *ERT =
829 static_cast<const RSExportRecordType*>(ET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700830
Stephen Hines6e6578a2011-02-07 18:05:48 -0800831 slangAssert((Val.getKind() == clang::APValue::Vector) &&
832 "Unexpected type of initializer for record type variable");
Shih-wei Liao9c631ff2010-09-17 11:57:29 -0700833
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700834 C.indent() << RS_EXPORT_VAR_PREFIX << VarName
835 << " = new "RS_TYPE_CLASS_NAME_PREFIX << ERT->getName()
836 << "."RS_TYPE_ITEM_CLASS_NAME"();" << std::endl;
Shih-wei Liao9c631ff2010-09-17 11:57:29 -0700837
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700838 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
839 E = ERT->fields_end();
840 I != E;
841 I++) {
842 const RSExportRecordType::Field *F = *I;
843 std::string FieldName = VarName + "." + F->getName();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700844
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700845 if (InitIndex > Val.getVectorLength())
846 break;
847
848 genInitPrimitiveExportVariable(C,
849 FieldName,
850 Val.getVectorElt(InitIndex++));
851 }
852#endif
Stephen Hines6e6578a2011-02-07 18:05:48 -0800853 slangAssert(false && "Unsupported initializer for record/matrix/constant "
854 "array type variable currently");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700855 break;
Shih-wei Liao6de89272010-07-15 15:26:20 -0700856 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700857 default: {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800858 slangAssert(false && "Unknown class of type");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700859 }
860 }
861 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700862}
863
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700864void RSReflection::genExportVariable(Context &C, const RSExportVar *EV) {
865 const RSExportType *ET = EV->getType();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700866
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700867 C.indent() << "private final static int "RS_EXPORT_VAR_INDEX_PREFIX
868 << EV->getName() << " = " << C.getNextExportVarSlot() << ";"
869 << std::endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700870
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700871 switch (ET->getClass()) {
Zonr Chang2e1dba62010-10-05 22:20:11 +0800872 case RSExportType::ExportClassPrimitive: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700873 genPrimitiveTypeExportVariable(C, EV);
874 break;
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700875 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700876 case RSExportType::ExportClassPointer: {
877 genPointerTypeExportVariable(C, EV);
878 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700879 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700880 case RSExportType::ExportClassVector: {
881 genVectorTypeExportVariable(C, EV);
882 break;
883 }
Zonr Chang92b344a2010-10-05 20:39:03 +0800884 case RSExportType::ExportClassMatrix: {
885 genMatrixTypeExportVariable(C, EV);
886 break;
887 }
Zonr Chang2e1dba62010-10-05 22:20:11 +0800888 case RSExportType::ExportClassConstantArray: {
889 genConstantArrayTypeExportVariable(C, EV);
890 break;
891 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700892 case RSExportType::ExportClassRecord: {
893 genRecordTypeExportVariable(C, EV);
894 break;
895 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700896 default: {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800897 slangAssert(false && "Unknown class of type");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700898 }
899 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700900
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700901 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700902}
903
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700904void RSReflection::genExportFunction(Context &C, const RSExportFunc *EF) {
905 C.indent() << "private final static int "RS_EXPORT_FUNC_INDEX_PREFIX
906 << EF->getName() << " = " << C.getNextExportFuncSlot() << ";"
907 << std::endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700908
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700909 // invoke_*()
910 Context::ArgTy Args;
911
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800912 if (EF->hasParam()) {
913 for (RSExportFunc::const_param_iterator I = EF->params_begin(),
914 E = EF->params_end();
915 I != E;
916 I++) {
917 Args.push_back(std::make_pair(GetTypeName((*I)->getType()),
918 (*I)->getName()));
919 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700920 }
921
922 C.startFunction(Context::AM_Public,
923 false,
924 "void",
Shih-wei Liao3fa286b2011-02-10 11:04:44 -0800925 "invoke_" + EF->getName(/*Mangle=*/ false),
926 // We are using un-mangled name since Java
927 // supports method overloading.
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700928 Args);
929
930 if (!EF->hasParam()) {
931 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ");"
932 << std::endl;
933 } else {
934 const RSExportRecordType *ERT = EF->getParamPacketType();
935 std::string FieldPackerName = EF->getName() + "_fp";
936
937 if (genCreateFieldPacker(C, ERT, FieldPackerName.c_str()))
938 genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str());
939
940 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ", "
941 << FieldPackerName << ");" << std::endl;
942 }
943
944 C.endFunction();
945 return;
946}
947
Stephen Hines593a8942011-05-10 15:29:50 -0700948void RSReflection::genExportForEach(Context &C, const RSExportForEach *EF) {
949 C.indent() << "private final static int "RS_EXPORT_FOREACH_INDEX_PREFIX
950 << EF->getName() << " = " << C.getNextExportForEachSlot() << ";"
951 << std::endl;
952
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700953 // forEach_*()
Stephen Hines593a8942011-05-10 15:29:50 -0700954 Context::ArgTy Args;
955
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700956 slangAssert(EF->getNumParameters() > 0);
Stephen Hines593a8942011-05-10 15:29:50 -0700957
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700958 if (EF->hasIn())
959 Args.push_back(std::make_pair("Allocation", "ain"));
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700960 if (EF->hasOut())
Stephen Hines593a8942011-05-10 15:29:50 -0700961 Args.push_back(std::make_pair("Allocation", "aout"));
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700962
963 const RSExportRecordType *ERT = EF->getParamPacketType();
964 if (ERT) {
965 for (RSExportForEach::const_param_iterator I = EF->params_begin(),
Stephen Hines593a8942011-05-10 15:29:50 -0700966 E = EF->params_end();
967 I != E;
968 I++) {
969 Args.push_back(std::make_pair(GetTypeName((*I)->getType()),
970 (*I)->getName()));
971 }
972 }
973
974 C.startFunction(Context::AM_Public,
975 false,
976 "void",
977 "forEach_" + EF->getName(),
978 Args);
979
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700980 const RSExportType *IET = EF->getInType();
981 if (IET) {
982 genTypeCheck(C, IET, "ain");
983 }
Stephen Hines593a8942011-05-10 15:29:50 -0700984
Stephen Hinesb5a89fb2011-05-17 14:48:02 -0700985 const RSExportType *OET = EF->getOutType();
986 if (OET) {
987 genTypeCheck(C, OET, "aout");
988 }
989
990 if (EF->hasIn() && EF->hasOut()) {
991 C.indent() << "// Verify dimensions" << std::endl;
992 C.indent() << "Type tIn = ain.getType();" << std::endl;
993 C.indent() << "Type tOut = aout.getType();" << std::endl;
994 C.indent() << "if ((tIn.getCount() != tOut.getCount()) ||" << std::endl;
995 C.indent() << " (tIn.getX() != tOut.getX()) ||" << std::endl;
996 C.indent() << " (tIn.getY() != tOut.getY()) ||" << std::endl;
997 C.indent() << " (tIn.getZ() != tOut.getZ()) ||" << std::endl;
998 C.indent() << " (tIn.hasFaces() != tOut.hasFaces()) ||" << std::endl;
999 C.indent() << " (tIn.hasMipmaps() != tOut.hasMipmaps())) {" << std::endl;
Stephen Hines48b72bf2011-06-10 15:37:27 -07001000 C.indent() << " throw new RSRuntimeException(\"Dimension mismatch "
1001 << "between input and output parameters!\");";
Stephen Hinesb5a89fb2011-05-17 14:48:02 -07001002 C.out() << std::endl;
1003 C.indent() << "}" << std::endl;
1004 }
1005
1006 std::string FieldPackerName = EF->getName() + "_fp";
1007 if (ERT) {
1008 if (genCreateFieldPacker(C, ERT, FieldPackerName.c_str())) {
Stephen Hines593a8942011-05-10 15:29:50 -07001009 genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str());
Stephen Hinesb5a89fb2011-05-17 14:48:02 -07001010 }
Stephen Hines593a8942011-05-10 15:29:50 -07001011 }
Stephen Hinesb5a89fb2011-05-17 14:48:02 -07001012 C.indent() << "forEach("RS_EXPORT_FOREACH_INDEX_PREFIX << EF->getName();
Stephen Hines593a8942011-05-10 15:29:50 -07001013
Stephen Hinesb5a89fb2011-05-17 14:48:02 -07001014 if (EF->hasIn())
1015 C.out() << ", ain";
1016 else
1017 C.out() << ", null";
1018
1019 if (EF->hasOut())
1020 C.out() << ", aout";
1021 else
1022 C.out() << ", null";
1023
1024 if (EF->hasUsrData())
1025 C.out() << ", " << FieldPackerName;
1026 else
1027 C.out() << ", null";
1028
1029 C.out() << ");" << std::endl;
Stephen Hines593a8942011-05-10 15:29:50 -07001030
1031 C.endFunction();
1032 return;
1033}
1034
Stephen Hines48b72bf2011-06-10 15:37:27 -07001035void RSReflection::genTypeInstance(Context &C,
1036 const RSExportType *ET) {
1037 if (ET->getClass() == RSExportType::ExportClassPointer) {
1038 const RSExportPointerType *EPT =
1039 static_cast<const RSExportPointerType*>(ET);
1040 ET = EPT->getPointeeType();
1041 switch (ET->getClass()) {
1042 case RSExportType::ExportClassPrimitive: {
1043 const RSExportPrimitiveType *EPT =
1044 static_cast<const RSExportPrimitiveType*>(ET);
1045 slangAssert(EPT);
1046
1047 switch (EPT->getKind()) {
1048 case RSExportPrimitiveType::DataKindPixelL:
1049 case RSExportPrimitiveType::DataKindPixelA:
1050 case RSExportPrimitiveType::DataKindPixelLA:
1051 case RSExportPrimitiveType::DataKindPixelRGB:
1052 case RSExportPrimitiveType::DataKindPixelRGBA: {
1053 break;
1054 }
1055
1056 case RSExportPrimitiveType::DataKindUser:
1057 default: {
1058 std::string TypeName = GetElementJavaTypeName(EPT->getType());
1059 if (C.mTypesToCheck.find(TypeName) == C.mTypesToCheck.end()) {
1060 C.indent() << "__" << TypeName << " = Element." << TypeName
1061 << "(rs);" << std::endl;
1062 C.mTypesToCheck.insert(TypeName);
1063 }
1064 break;
1065 }
1066 }
1067 break;
1068 }
1069
1070 case RSExportType::ExportClassVector: {
1071 const RSExportVectorType *EVT =
1072 static_cast<const RSExportVectorType*>(ET);
1073 slangAssert(EVT);
1074
1075 const char *TypeName = GetVectorElementName(EVT);
1076 if (C.mTypesToCheck.find(TypeName) == C.mTypesToCheck.end()) {
1077 C.indent() << "__" << TypeName << " = Element." << TypeName
1078 << "(rs);" << std::endl;
1079 C.mTypesToCheck.insert(TypeName);
1080 }
1081 break;
1082 }
1083
1084 case RSExportType::ExportClassRecord: {
1085 const RSExportRecordType *ERT =
1086 static_cast<const RSExportRecordType*>(ET);
1087 slangAssert(ERT);
1088
1089 std::string ClassName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName();
1090 if (C.mTypesToCheck.find(ClassName) == C.mTypesToCheck.end()) {
1091 C.indent() << "__" << ClassName << " = " << ClassName <<
1092 ".createElement(rs);" << std::endl;
1093 C.mTypesToCheck.insert(ClassName);
1094 }
1095 break;
1096 }
1097
1098 default:
1099 break;
1100 }
1101 }
1102}
1103
Stephen Hinesb5a89fb2011-05-17 14:48:02 -07001104void RSReflection::genTypeCheck(Context &C,
1105 const RSExportType *ET,
1106 const char *VarName) {
1107 C.indent() << "// check " << VarName << std::endl;
Stephen Hines48b72bf2011-06-10 15:37:27 -07001108
1109 if (ET->getClass() == RSExportType::ExportClassPointer) {
1110 const RSExportPointerType *EPT =
1111 static_cast<const RSExportPointerType*>(ET);
1112 ET = EPT->getPointeeType();
1113 }
1114
1115 std::string TypeName;
1116
1117 switch (ET->getClass()) {
1118 case RSExportType::ExportClassPrimitive: {
1119 const RSExportPrimitiveType *EPT =
1120 static_cast<const RSExportPrimitiveType*>(ET);
1121 slangAssert(EPT);
1122
1123 if (EPT->getKind() == RSExportPrimitiveType::DataKindUser) {
1124 TypeName = GetElementJavaTypeName(EPT->getType());
1125 }
1126 break;
1127 }
1128
1129 case RSExportType::ExportClassVector: {
1130 const RSExportVectorType *EVT =
1131 static_cast<const RSExportVectorType*>(ET);
1132 slangAssert(EVT);
1133 TypeName = GetVectorElementName(EVT);
1134 break;
1135 }
1136
1137 case RSExportType::ExportClassRecord: {
1138 const RSExportRecordType *ERT =
1139 static_cast<const RSExportRecordType*>(ET);
1140 slangAssert(ERT);
1141 TypeName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName();
1142 break;
1143 }
1144
1145 default:
1146 break;
1147 }
1148
1149 if (!TypeName.empty()) {
1150 C.indent() << "if (!" << VarName
1151 << ".getType().getElement().isCompatible(__"
1152 << TypeName << ")) {" << std::endl;
1153 C.indent() << " throw new RSRuntimeException(\"Type mismatch with "
1154 << TypeName << "!\");" << std::endl;
1155 C.indent() << "}" << std::endl;
1156 }
1157
Stephen Hinesb5a89fb2011-05-17 14:48:02 -07001158 return;
1159}
1160
1161
Stephen Hinese639eb52010-11-08 19:27:20 -08001162void RSReflection::genPrimitiveTypeExportVariable(
1163 Context &C,
1164 const RSExportVar *EV) {
Stephen Hines6e6578a2011-02-07 18:05:48 -08001165 slangAssert((EV->getType()->getClass() == RSExportType::ExportClassPrimitive)
1166 && "Variable should be type of primitive here");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001167
1168 const RSExportPrimitiveType *EPT =
1169 static_cast<const RSExportPrimitiveType*>(EV->getType());
1170 const char *TypeName = GetPrimitiveTypeName(EPT);
1171
1172 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
1173 << EV->getName() << ";" << std::endl;
1174
1175 // set_*()
1176 if (!EV->isConst()) {
1177 C.startFunction(Context::AM_Public,
1178 false,
1179 "void",
1180 "set_" + EV->getName(),
1181 1,
Zonr Changd42a4292010-10-17 02:38:43 +08001182 TypeName, "v");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001183 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
1184
Jason Sams650c02b2010-11-16 18:00:56 -08001185 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName()
1186 << ", v);" << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001187
Shih-wei Liao9e86e192010-06-18 20:42:28 -07001188 C.endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001189 }
Shih-wei Liao9e86e192010-06-18 20:42:28 -07001190
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001191 genGetExportVariable(C, TypeName, EV->getName());
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001192
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001193 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001194}
1195
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001196void RSReflection::genPointerTypeExportVariable(Context &C,
1197 const RSExportVar *EV) {
1198 const RSExportType *ET = EV->getType();
1199 const RSExportType *PointeeType;
1200 std::string TypeName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001201
Stephen Hines6e6578a2011-02-07 18:05:48 -08001202 slangAssert((ET->getClass() == RSExportType::ExportClassPointer) &&
1203 "Variable should be type of pointer here");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001204
1205 PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType();
1206 TypeName = GetTypeName(ET);
1207
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001208 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
1209 << EV->getName() << ";" << std::endl;
1210
Zonr Chang89273bd2010-10-14 20:57:38 +08001211 // bind_*()
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001212 C.startFunction(Context::AM_Public,
1213 false,
1214 "void",
1215 "bind_" + EV->getName(),
1216 1,
Zonr Changd42a4292010-10-17 02:38:43 +08001217 TypeName.c_str(), "v");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001218
1219 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
1220 C.indent() << "if (v == null) bindAllocation(null, "RS_EXPORT_VAR_INDEX_PREFIX
1221 << EV->getName() << ");" << std::endl;
1222
1223 if (PointeeType->getClass() == RSExportType::ExportClassRecord)
1224 C.indent() << "else bindAllocation(v.getAllocation(), "
1225 RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");"
1226 << std::endl;
1227 else
1228 C.indent() << "else bindAllocation(v, "RS_EXPORT_VAR_INDEX_PREFIX
1229 << EV->getName() << ");" << std::endl;
1230
1231 C.endFunction();
1232
1233 genGetExportVariable(C, TypeName, EV->getName());
1234
1235 return;
1236}
1237
1238void RSReflection::genVectorTypeExportVariable(Context &C,
1239 const RSExportVar *EV) {
Stephen Hines6e6578a2011-02-07 18:05:48 -08001240 slangAssert((EV->getType()->getClass() == RSExportType::ExportClassVector) &&
1241 "Variable should be type of vector here");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001242
1243 const RSExportVectorType *EVT =
1244 static_cast<const RSExportVectorType*>(EV->getType());
1245 const char *TypeName = GetVectorTypeName(EVT);
1246 const char *FieldPackerName = "fp";
1247
1248 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
1249 << EV->getName() << ";" << std::endl;
1250
1251 // set_*()
1252 if (!EV->isConst()) {
1253 C.startFunction(Context::AM_Public,
1254 false,
1255 "void",
1256 "set_" + EV->getName(),
1257 1,
Zonr Changd42a4292010-10-17 02:38:43 +08001258 TypeName, "v");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001259 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
1260
1261 if (genCreateFieldPacker(C, EVT, FieldPackerName))
1262 genPackVarOfType(C, EVT, "v", FieldPackerName);
1263 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", "
1264 << FieldPackerName << ");" << std::endl;
1265
1266 C.endFunction();
1267 }
1268
1269 genGetExportVariable(C, TypeName, EV->getName());
1270 return;
1271}
1272
Zonr Chang92b344a2010-10-05 20:39:03 +08001273void RSReflection::genMatrixTypeExportVariable(Context &C,
1274 const RSExportVar *EV) {
Stephen Hines6e6578a2011-02-07 18:05:48 -08001275 slangAssert((EV->getType()->getClass() == RSExportType::ExportClassMatrix) &&
1276 "Variable should be type of matrix here");
Zonr Chang92b344a2010-10-05 20:39:03 +08001277
1278 const RSExportMatrixType *EMT =
1279 static_cast<const RSExportMatrixType*>(EV->getType());
1280 const char *TypeName = GetMatrixTypeName(EMT);
1281 const char *FieldPackerName = "fp";
1282
1283 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
1284 << EV->getName() << ";" << std::endl;
1285
1286 // set_*()
1287 if (!EV->isConst()) {
1288 C.startFunction(Context::AM_Public,
1289 false,
1290 "void",
1291 "set_" + EV->getName(),
1292 1,
1293 TypeName, "v");
1294 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
1295
1296 if (genCreateFieldPacker(C, EMT, FieldPackerName))
1297 genPackVarOfType(C, EMT, "v", FieldPackerName);
1298 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", "
1299 << FieldPackerName << ");" << std::endl;
1300
1301 C.endFunction();
1302 }
1303
1304 genGetExportVariable(C, TypeName, EV->getName());
1305 return;
1306}
1307
Stephen Hinese639eb52010-11-08 19:27:20 -08001308void RSReflection::genConstantArrayTypeExportVariable(
1309 Context &C,
1310 const RSExportVar *EV) {
Stephen Hines6e6578a2011-02-07 18:05:48 -08001311 slangAssert((EV->getType()->getClass() ==
1312 RSExportType::ExportClassConstantArray) &&
1313 "Variable should be type of constant array here");
Zonr Chang2e1dba62010-10-05 22:20:11 +08001314
1315 const RSExportConstantArrayType *ECAT =
1316 static_cast<const RSExportConstantArrayType*>(EV->getType());
1317 std::string TypeName = GetTypeName(ECAT);
1318 const char *FieldPackerName = "fp";
1319
1320 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
1321 << EV->getName() << ";" << std::endl;
1322
1323 // set_*()
1324 if (!EV->isConst()) {
1325 C.startFunction(Context::AM_Public,
1326 false,
1327 "void",
1328 "set_" + EV->getName(),
1329 1,
1330 TypeName.c_str(), "v");
1331 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
1332
1333 if (genCreateFieldPacker(C, ECAT, FieldPackerName))
1334 genPackVarOfType(C, ECAT, "v", FieldPackerName);
1335 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", "
1336 << FieldPackerName << ");" << std::endl;
1337
1338 C.endFunction();
1339 }
1340
1341 genGetExportVariable(C, TypeName, EV->getName());
1342 return;
1343}
1344
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001345void RSReflection::genRecordTypeExportVariable(Context &C,
1346 const RSExportVar *EV) {
Stephen Hines6e6578a2011-02-07 18:05:48 -08001347 slangAssert((EV->getType()->getClass() == RSExportType::ExportClassRecord) &&
1348 "Variable should be type of struct here");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001349
1350 const RSExportRecordType *ERT =
1351 static_cast<const RSExportRecordType*>(EV->getType());
1352 std::string TypeName =
1353 RS_TYPE_CLASS_NAME_PREFIX + ERT->getName() + "."RS_TYPE_ITEM_CLASS_NAME;
1354 const char *FieldPackerName = "fp";
1355
1356 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
1357 << EV->getName() << ";" << std::endl;
1358
1359 // set_*()
1360 if (!EV->isConst()) {
1361 C.startFunction(Context::AM_Public,
1362 false,
1363 "void",
1364 "set_" + EV->getName(),
1365 1,
Zonr Changd42a4292010-10-17 02:38:43 +08001366 TypeName.c_str(), "v");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001367 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
1368
1369 if (genCreateFieldPacker(C, ERT, FieldPackerName))
1370 genPackVarOfType(C, ERT, "v", FieldPackerName);
1371 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName()
1372 << ", " << FieldPackerName << ");" << std::endl;
1373
1374 C.endFunction();
1375 }
1376
1377 genGetExportVariable(C, TypeName.c_str(), EV->getName());
1378 return;
1379}
1380
1381void RSReflection::genGetExportVariable(Context &C,
1382 const std::string &TypeName,
1383 const std::string &VarName) {
1384 C.startFunction(Context::AM_Public,
1385 false,
1386 TypeName.c_str(),
1387 "get_" + VarName,
1388 0);
1389
1390 C.indent() << "return "RS_EXPORT_VAR_PREFIX << VarName << ";" << std::endl;
1391
1392 C.endFunction();
1393 return;
1394}
1395
1396/******************* Methods to generate script class /end *******************/
1397
1398bool RSReflection::genCreateFieldPacker(Context &C,
1399 const RSExportType *ET,
1400 const char *FieldPackerName) {
1401 size_t AllocSize = RSExportType::GetTypeAllocSize(ET);
1402 if (AllocSize > 0)
1403 C.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker("
1404 << AllocSize << ");" << std::endl;
1405 else
1406 return false;
1407 return true;
1408}
1409
1410void RSReflection::genPackVarOfType(Context &C,
1411 const RSExportType *ET,
1412 const char *VarName,
1413 const char *FieldPackerName) {
1414 switch (ET->getClass()) {
1415 case RSExportType::ExportClassPrimitive:
1416 case RSExportType::ExportClassVector: {
1417 C.indent() << FieldPackerName << "."
1418 << GetPackerAPIName(
1419 static_cast<const RSExportPrimitiveType*>(ET))
1420 << "(" << VarName << ");" << std::endl;
1421 break;
1422 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001423 case RSExportType::ExportClassPointer: {
1424 // Must reflect as type Allocation in Java
1425 const RSExportType *PointeeType =
1426 static_cast<const RSExportPointerType*>(ET)->getPointeeType();
1427
1428 if (PointeeType->getClass() != RSExportType::ExportClassRecord)
1429 C.indent() << FieldPackerName << ".addI32(" << VarName
1430 << ".getPtr());" << std::endl;
1431 else
1432 C.indent() << FieldPackerName << ".addI32(" << VarName
1433 << ".getAllocation().getPtr());" << std::endl;
1434 break;
1435 }
Zonr Chang92b344a2010-10-05 20:39:03 +08001436 case RSExportType::ExportClassMatrix: {
Alex Sakhartchoukaa180e92010-12-17 13:26:07 -08001437 C.indent() << FieldPackerName << ".addMatrix(" << VarName << ");"
Zonr Chang92b344a2010-10-05 20:39:03 +08001438 << std::endl;
1439 break;
1440 }
Zonr Chang2e1dba62010-10-05 22:20:11 +08001441 case RSExportType::ExportClassConstantArray: {
1442 const RSExportConstantArrayType *ECAT =
1443 static_cast<const RSExportConstantArrayType *>(ET);
Zonr Chang89273bd2010-10-14 20:57:38 +08001444
1445 // TODO(zonr): more elegant way. Currently, we obtain the unique index
1446 // variable (this method involves recursive call which means
1447 // we may have more than one level loop, therefore we can't
1448 // always use the same index variable name here) name given
1449 // in the for-loop from counting the '.' in @VarName.
1450 unsigned Level = 0;
1451 size_t LastDotPos = 0;
1452 std::string ElementVarName(VarName);
1453
1454 while (LastDotPos != std::string::npos) {
1455 LastDotPos = ElementVarName.find_first_of('.', LastDotPos + 1);
1456 Level++;
1457 }
1458 std::string IndexVarName("ct");
1459 IndexVarName.append(llvm::utostr_32(Level));
1460
1461 C.indent() << "for (int " << IndexVarName << " = 0; " <<
1462 IndexVarName << " < " << ECAT->getSize() << "; " <<
1463 IndexVarName << "++)";
Zonr Chang2e1dba62010-10-05 22:20:11 +08001464 C.startBlock();
1465
Zonr Chang89273bd2010-10-14 20:57:38 +08001466 ElementVarName.append("[" + IndexVarName + "]");
Zonr Chang2e1dba62010-10-05 22:20:11 +08001467 genPackVarOfType(C, ECAT->getElementType(), ElementVarName.c_str(),
1468 FieldPackerName);
1469
1470 C.endBlock();
1471 break;
1472 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001473 case RSExportType::ExportClassRecord: {
zonr6315f762010-10-05 15:35:14 +08001474 const RSExportRecordType *ERT =
1475 static_cast<const RSExportRecordType*>(ET);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001476 // Relative pos from now on in field packer
1477 unsigned Pos = 0;
1478
1479 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
1480 E = ERT->fields_end();
1481 I != E;
1482 I++) {
1483 const RSExportRecordType::Field *F = *I;
1484 std::string FieldName;
1485 size_t FieldOffset = F->getOffsetInParent();
1486 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
1487 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType());
1488
1489 if (VarName != NULL)
1490 FieldName = VarName + ("." + F->getName());
1491 else
1492 FieldName = F->getName();
1493
1494 if (FieldOffset > Pos)
1495 C.indent() << FieldPackerName << ".skip("
1496 << (FieldOffset - Pos) << ");" << std::endl;
1497
1498 genPackVarOfType(C, F->getType(), FieldName.c_str(), FieldPackerName);
1499
1500 // There is padding in the field type
1501 if (FieldAllocSize > FieldStoreSize)
1502 C.indent() << FieldPackerName << ".skip("
1503 << (FieldAllocSize - FieldStoreSize)
1504 << ");" << std::endl;
1505
1506 Pos = FieldOffset + FieldAllocSize;
1507 }
1508
1509 // There maybe some padding after the struct
Andrew Hsiehd22724a2011-07-20 18:03:56 -07001510 if (RSExportType::GetTypeAllocSize(ERT) > Pos)
Stephen Hines6b201eb2011-07-20 17:08:16 -07001511 C.indent() << FieldPackerName << ".skip("
Andrew Hsiehd22724a2011-07-20 18:03:56 -07001512 << RSExportType::GetTypeAllocSize(ERT) - Pos << ");"
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001513 << std::endl;
1514 break;
1515 }
1516 default: {
Stephen Hines6e6578a2011-02-07 18:05:48 -08001517 slangAssert(false && "Unknown class of type");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001518 }
1519 }
1520
1521 return;
1522}
1523
Zonr Chang2e1dba62010-10-05 22:20:11 +08001524void RSReflection::genAllocateVarOfType(Context &C,
1525 const RSExportType *T,
1526 const std::string &VarName) {
1527 switch (T->getClass()) {
1528 case RSExportType::ExportClassPrimitive: {
1529 // Primitive type like int in Java has its own storage once it's declared.
1530 //
1531 // FIXME: Should we allocate storage for RS object?
1532 // if (static_cast<const RSExportPrimitiveType *>(T)->isRSObjectType())
1533 // C.indent() << VarName << " = new " << GetTypeName(T) << "();"
1534 // << std::endl;
1535 break;
1536 }
1537 case RSExportType::ExportClassPointer: {
1538 // Pointer type is an instance of Allocation or a TypeClass whose value is
1539 // expected to be assigned by programmer later in Java program. Therefore
1540 // we don't reflect things like [VarName] = new Allocation();
1541 C.indent() << VarName << " = null;" << std::endl;
1542 break;
1543 }
1544 case RSExportType::ExportClassConstantArray: {
1545 const RSExportConstantArrayType *ECAT =
1546 static_cast<const RSExportConstantArrayType *>(T);
1547 const RSExportType *ElementType = ECAT->getElementType();
1548
Zonr Chang2f1451c2010-10-14 02:58:28 +08001549 C.indent() << VarName << " = new " << GetTypeName(ElementType)
1550 << "[" << ECAT->getSize() << "];" << std::endl;
1551
Zonr Chang2e1dba62010-10-05 22:20:11 +08001552 // Primitive type element doesn't need allocation code.
1553 if (ElementType->getClass() != RSExportType::ExportClassPrimitive) {
Zonr Chang2e1dba62010-10-05 22:20:11 +08001554 C.indent() << "for (int $ct = 0; $ct < " << ECAT->getSize() << "; "
1555 "$ct++)";
1556 C.startBlock();
1557
1558 std::string ElementVarName(VarName);
1559 ElementVarName.append("[$ct]");
1560 genAllocateVarOfType(C, ElementType, ElementVarName);
1561
1562 C.endBlock();
1563 }
1564 break;
1565 }
1566 case RSExportType::ExportClassVector:
1567 case RSExportType::ExportClassMatrix:
1568 case RSExportType::ExportClassRecord: {
1569 C.indent() << VarName << " = new " << GetTypeName(T) << "();"
1570 << std::endl;
1571 break;
1572 }
1573 }
1574 return;
1575}
1576
Stephen Hinese639eb52010-11-08 19:27:20 -08001577void RSReflection::genNewItemBufferIfNull(Context &C,
1578 const char *Index) {
1579 C.indent() << "if (" RS_TYPE_ITEM_BUFFER_NAME " == null) "
1580 RS_TYPE_ITEM_BUFFER_NAME " = "
1581 "new " RS_TYPE_ITEM_CLASS_NAME
1582 "[getType().getX() /* count */];"
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001583 << std::endl;
1584 if (Index != NULL)
1585 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] == null) "
Zonr Chang92b344a2010-10-05 20:39:03 +08001586 RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] = "
1587 "new "RS_TYPE_ITEM_CLASS_NAME"();" << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001588 return;
1589}
1590
1591void RSReflection::genNewItemBufferPackerIfNull(Context &C) {
Stephen Hinese639eb52010-11-08 19:27:20 -08001592 C.indent() << "if (" RS_TYPE_ITEM_BUFFER_PACKER_NAME " == null) "
1593 RS_TYPE_ITEM_BUFFER_PACKER_NAME " = "
1594 "new FieldPacker(" RS_TYPE_ITEM_CLASS_NAME
1595 ".sizeof * getType().getX()/* count */"
1596 ");" << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001597 return;
1598}
1599
1600/********************** Methods to generate type class **********************/
1601bool RSReflection::genTypeClass(Context &C,
1602 const RSExportRecordType *ERT,
1603 std::string &ErrorMsg) {
1604 std::string ClassName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName();
1605
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001606 if (!C.startClass(Context::AM_Public,
1607 false,
1608 ClassName,
1609 RS_TYPE_CLASS_SUPER_CLASS_NAME,
1610 ErrorMsg))
1611 return false;
1612
Stephen Hines4cc67fc2011-01-31 16:48:57 -08001613 mGeneratedFileNames->push_back(ClassName);
1614
Zonr Chang2e1dba62010-10-05 22:20:11 +08001615 genTypeItemClass(C, ERT);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001616
1617 // Declare item buffer and item buffer packer
1618 C.indent() << "private "RS_TYPE_ITEM_CLASS_NAME" "RS_TYPE_ITEM_BUFFER_NAME"[]"
1619 ";" << std::endl;
1620 C.indent() << "private FieldPacker "RS_TYPE_ITEM_BUFFER_PACKER_NAME";"
1621 << std::endl;
1622
1623 genTypeClassConstructor(C, ERT);
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001624 genTypeClassCopyToArrayLocal(C, ERT);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001625 genTypeClassCopyToArray(C, ERT);
1626 genTypeClassItemSetter(C, ERT);
1627 genTypeClassItemGetter(C, ERT);
1628 genTypeClassComponentSetter(C, ERT);
1629 genTypeClassComponentGetter(C, ERT);
1630 genTypeClassCopyAll(C, ERT);
Zonr Changd42a4292010-10-17 02:38:43 +08001631 genTypeClassResize(C);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001632
1633 C.endClass();
1634
Zonr Chang66aa2992010-10-05 15:56:31 +08001635 C.resetFieldIndex();
1636 C.clearFieldIndexMap();
1637
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001638 return true;
1639}
1640
Stephen Hinese639eb52010-11-08 19:27:20 -08001641void RSReflection::genTypeItemClass(Context &C,
1642 const RSExportRecordType *ERT) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001643 C.indent() << "static public class "RS_TYPE_ITEM_CLASS_NAME;
1644 C.startBlock();
1645
1646 C.indent() << "public static final int sizeof = "
1647 << RSExportType::GetTypeAllocSize(ERT) << ";" << std::endl;
1648
1649 // Member elements
1650 C.out() << std::endl;
1651 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
1652 FE = ERT->fields_end();
1653 FI != FE;
1654 FI++) {
1655 C.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName()
1656 << ";" << std::endl;
1657 }
1658
1659 // Constructor
1660 C.out() << std::endl;
1661 C.indent() << RS_TYPE_ITEM_CLASS_NAME"()";
1662 C.startBlock();
1663
1664 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
1665 FE = ERT->fields_end();
1666 FI != FE;
1667 FI++) {
1668 const RSExportRecordType::Field *F = *FI;
Zonr Chang2e1dba62010-10-05 22:20:11 +08001669 genAllocateVarOfType(C, F->getType(), F->getName());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001670 }
1671
1672 // end Constructor
1673 C.endBlock();
1674
1675 // end Item class
1676 C.endBlock();
1677
Zonr Chang2e1dba62010-10-05 22:20:11 +08001678 return;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001679}
1680
1681void RSReflection::genTypeClassConstructor(Context &C,
1682 const RSExportRecordType *ERT) {
1683 const char *RenderScriptVar = "rs";
1684
1685 C.startFunction(Context::AM_Public,
1686 true,
1687 "Element",
1688 "createElement",
1689 1,
Zonr Changd42a4292010-10-17 02:38:43 +08001690 "RenderScript", RenderScriptVar);
Zonr Chang89273bd2010-10-14 20:57:38 +08001691 genBuildElement(C, "eb", ERT, RenderScriptVar, /* IsInline = */false);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001692 C.endFunction();
1693
1694 C.startFunction(Context::AM_Public,
1695 false,
1696 NULL,
1697 C.getClassName(),
1698 2,
Zonr Changd42a4292010-10-17 02:38:43 +08001699 "RenderScript", RenderScriptVar,
1700 "int", "count");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001701
1702 C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << std::endl;
1703 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << std::endl;
1704 C.indent() << "mElement = createElement(" << RenderScriptVar << ");"
1705 << std::endl;
1706 // Call init() in super class
1707 C.indent() << "init(" << RenderScriptVar << ", count);" << std::endl;
1708 C.endFunction();
1709
Jason Sams91fe83b2010-12-06 17:07:12 -08001710 C.startFunction(Context::AM_Public,
1711 false,
1712 NULL,
1713 C.getClassName(),
1714 3,
1715 "RenderScript", RenderScriptVar,
1716 "int", "count",
1717 "int", "usages");
1718
1719 C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << std::endl;
1720 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << std::endl;
1721 C.indent() << "mElement = createElement(" << RenderScriptVar << ");"
1722 << std::endl;
1723 // Call init() in super class
1724 C.indent() << "init(" << RenderScriptVar << ", count, usages);" << std::endl;
1725 C.endFunction();
1726
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001727 return;
1728}
1729
1730void RSReflection::genTypeClassCopyToArray(Context &C,
1731 const RSExportRecordType *ERT) {
1732 C.startFunction(Context::AM_Private,
1733 false,
1734 "void",
1735 "copyToArray",
1736 2,
Zonr Changd42a4292010-10-17 02:38:43 +08001737 RS_TYPE_ITEM_CLASS_NAME, "i",
1738 "int", "index");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001739
1740 genNewItemBufferPackerIfNull(C);
1741 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME
Zonr Chang92b344a2010-10-05 20:39:03 +08001742 ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);"
1743 << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001744
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001745 C.indent() << "copyToArrayLocal(i, " RS_TYPE_ITEM_BUFFER_PACKER_NAME
1746 ");" << std::endl;
1747
1748 C.endFunction();
1749 return;
1750}
1751
1752void RSReflection::genTypeClassCopyToArrayLocal(Context &C,
1753 const RSExportRecordType *ERT) {
1754 C.startFunction(Context::AM_Private,
1755 false,
1756 "void",
1757 "copyToArrayLocal",
1758 2,
1759 RS_TYPE_ITEM_CLASS_NAME, "i",
1760 "FieldPacker", "fp");
1761
1762 genPackVarOfType(C, ERT, "i", "fp");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001763
1764 C.endFunction();
1765 return;
1766}
1767
1768void RSReflection::genTypeClassItemSetter(Context &C,
zonr6315f762010-10-05 15:35:14 +08001769 const RSExportRecordType *ERT) {
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001770 C.startFunction(Context::AM_PublicSynchronized,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001771 false,
1772 "void",
1773 "set",
1774 3,
Zonr Changd42a4292010-10-17 02:38:43 +08001775 RS_TYPE_ITEM_CLASS_NAME, "i",
1776 "int", "index",
1777 "boolean", "copyNow");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001778 genNewItemBufferIfNull(C, NULL);
1779 C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index] = i;" << std::endl;
1780
1781 C.indent() << "if (copyNow) ";
1782 C.startBlock();
1783
1784 C.indent() << "copyToArray(i, index);" << std::endl;
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001785 C.indent() << "FieldPacker fp = new FieldPacker(" RS_TYPE_ITEM_CLASS_NAME
1786 ".sizeof);" << std::endl;
1787 C.indent() << "copyToArrayLocal(i, fp);" << std::endl;
1788 C.indent() << "mAllocation.setFromFieldPacker(index, fp);" << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001789
1790 // End of if (copyNow)
1791 C.endBlock();
1792
1793 C.endFunction();
1794 return;
1795}
1796
1797void RSReflection::genTypeClassItemGetter(Context &C,
1798 const RSExportRecordType *ERT) {
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001799 C.startFunction(Context::AM_PublicSynchronized,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001800 false,
1801 RS_TYPE_ITEM_CLASS_NAME,
1802 "get",
1803 1,
Zonr Changd42a4292010-10-17 02:38:43 +08001804 "int", "index");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001805 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return null;"
1806 << std::endl;
1807 C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index];" << std::endl;
1808 C.endFunction();
1809 return;
1810}
1811
1812void RSReflection::genTypeClassComponentSetter(Context &C,
1813 const RSExportRecordType *ERT) {
1814 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
1815 FE = ERT->fields_end();
1816 FI != FE;
1817 FI++) {
1818 const RSExportRecordType::Field *F = *FI;
1819 size_t FieldOffset = F->getOffsetInParent();
1820 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
1821 unsigned FieldIndex = C.getFieldIndex(F);
1822
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001823 C.startFunction(Context::AM_PublicSynchronized,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001824 false,
1825 "void",
1826 "set_" + F->getName(), 3,
Zonr Changd42a4292010-10-17 02:38:43 +08001827 "int", "index",
1828 GetTypeName(F->getType()).c_str(), "v",
1829 "boolean", "copyNow");
Shih-wei Liao9c631ff2010-09-17 11:57:29 -07001830 genNewItemBufferPackerIfNull(C);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001831 genNewItemBufferIfNull(C, "index");
1832 C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName()
1833 << " = v;" << std::endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001834
1835 C.indent() << "if (copyNow) ";
1836 C.startBlock();
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -07001837
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001838 if (FieldOffset > 0)
Zonr Chang92b344a2010-10-05 20:39:03 +08001839 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME
1840 ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof + "
1841 << FieldOffset << ");" << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001842 else
Zonr Chang92b344a2010-10-05 20:39:03 +08001843 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME
1844 ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);"
1845 << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001846 genPackVarOfType(C, F->getType(), "v", RS_TYPE_ITEM_BUFFER_PACKER_NAME);
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001847
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001848 C.indent() << "FieldPacker fp = new FieldPacker(" << FieldStoreSize << ");"
1849 << std::endl;
1850 genPackVarOfType(C, F->getType(), "v", "fp");
Jason Samsa036a8a2011-01-16 14:52:39 -08001851 C.indent() << "mAllocation.setFromFieldPacker(index, " << FieldIndex
Stephen Hines32917932011-01-11 20:51:53 -08001852 << ", fp);"
Zonr Chang66aa2992010-10-05 15:56:31 +08001853 << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001854
1855 // End of if (copyNow)
1856 C.endBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001857
1858 C.endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001859 }
1860 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001861}
1862
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001863void RSReflection::genTypeClassComponentGetter(Context &C,
1864 const RSExportRecordType *ERT) {
1865 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
1866 FE = ERT->fields_end();
1867 FI != FE;
1868 FI++) {
1869 const RSExportRecordType::Field *F = *FI;
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001870 C.startFunction(Context::AM_PublicSynchronized,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001871 false,
1872 GetTypeName(F->getType()).c_str(),
1873 "get_" + F->getName(),
1874 1,
Zonr Changd42a4292010-10-17 02:38:43 +08001875 "int", "index");
Shih-wei Liaocf950c42010-10-06 03:44:40 -07001876 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return "
1877 << GetTypeNullValue(F->getType()) << ";" << std::endl;
zonr6315f762010-10-05 15:35:14 +08001878 C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName()
1879 << ";" << std::endl;
Shih-wei Liao9b1f50b2010-08-05 12:40:41 -07001880 C.endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001881 }
1882 return;
Shih-wei Liao9c631ff2010-09-17 11:57:29 -07001883}
1884
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001885void RSReflection::genTypeClassCopyAll(Context &C,
1886 const RSExportRecordType *ERT) {
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001887 C.startFunction(Context::AM_PublicSynchronized, false, "void", "copyAll", 0);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001888
Zonr Chang2e1dba62010-10-05 22:20:11 +08001889 C.indent() << "for (int ct = 0; ct < "RS_TYPE_ITEM_BUFFER_NAME".length; ct++)"
1890 " copyToArray("RS_TYPE_ITEM_BUFFER_NAME"[ct], ct);"
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001891 << std::endl;
Stephen Hines06617782011-01-17 12:24:01 -08001892 C.indent() << "mAllocation.setFromFieldPacker(0, "
1893 RS_TYPE_ITEM_BUFFER_PACKER_NAME");"
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001894 << std::endl;
1895
1896 C.endFunction();
1897 return;
Shih-wei Liao9c631ff2010-09-17 11:57:29 -07001898}
1899
Zonr Changd42a4292010-10-17 02:38:43 +08001900void RSReflection::genTypeClassResize(Context &C) {
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07001901 C.startFunction(Context::AM_PublicSynchronized,
Zonr Changd42a4292010-10-17 02:38:43 +08001902 false,
1903 "void",
1904 "resize",
1905 1,
1906 "int", "newSize");
1907
Jason Sams3caea7d2010-10-25 18:15:53 -07001908 C.indent() << "if (mItemArray != null) ";
1909 C.startBlock();
Zonr Changd42a4292010-10-17 02:38:43 +08001910 C.indent() << "int oldSize = mItemArray.length;" << std::endl;
1911 C.indent() << "int copySize = Math.min(oldSize, newSize);" << std::endl;
Jason Sams3caea7d2010-10-25 18:15:53 -07001912 C.indent() << "if (newSize == oldSize) return;" << std::endl;
Zonr Changd42a4292010-10-17 02:38:43 +08001913 C.indent() << "Item ni[] = new Item[newSize];" << std::endl;
1914 C.indent() << "System.arraycopy(mItemArray, 0, ni, 0, copySize);"
1915 << std::endl;
1916 C.indent() << "mItemArray = ni;" << std::endl;
Jason Sams3caea7d2010-10-25 18:15:53 -07001917 C.endBlock();
Zonr Changd42a4292010-10-17 02:38:43 +08001918 C.indent() << "mAllocation.resize(newSize);" << std::endl;
1919
Jason Samscedffd92010-12-16 15:29:49 -08001920 C.indent() << "if (" RS_TYPE_ITEM_BUFFER_PACKER_NAME " != null) "
1921 RS_TYPE_ITEM_BUFFER_PACKER_NAME " = "
1922 "new FieldPacker(" RS_TYPE_ITEM_CLASS_NAME
1923 ".sizeof * getType().getX()/* count */"
1924 ");" << std::endl;
1925
Zonr Changd42a4292010-10-17 02:38:43 +08001926 C.endFunction();
1927 return;
1928}
1929
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001930/******************** Methods to generate type class /end ********************/
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001931
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001932/********** Methods to create Element in Java of given record type ***********/
Zonr Chang89273bd2010-10-14 20:57:38 +08001933void RSReflection::genBuildElement(Context &C,
1934 const char *ElementBuilderName,
1935 const RSExportRecordType *ERT,
1936 const char *RenderScriptVar,
1937 bool IsInline) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001938 C.indent() << "Element.Builder " << ElementBuilderName << " = "
1939 "new Element.Builder(" << RenderScriptVar << ");" << std::endl;
1940
1941 // eb.add(...)
1942 genAddElementToElementBuilder(C,
1943 ERT,
1944 "",
1945 ElementBuilderName,
Zonr Chang89273bd2010-10-14 20:57:38 +08001946 RenderScriptVar,
1947 /* ArraySize = */0);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001948
Zonr Chang89273bd2010-10-14 20:57:38 +08001949 if (!IsInline)
1950 C.indent() << "return " << ElementBuilderName << ".create();" << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001951 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001952}
1953
Zonr Chang89273bd2010-10-14 20:57:38 +08001954#define EB_ADD(x) do { \
Zonr Chang92b344a2010-10-05 20:39:03 +08001955 C.indent() << ElementBuilderName \
Zonr Chang89273bd2010-10-14 20:57:38 +08001956 << ".add(" << x << ", \"" << VarName << "\""; \
1957 if (ArraySize > 0) \
1958 C.out() << ", " << ArraySize; \
1959 C.out() << ");" << std::endl; \
1960 C.incFieldIndex(); \
1961} while (false)
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001962
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001963void RSReflection::genAddElementToElementBuilder(Context &C,
1964 const RSExportType *ET,
1965 const std::string &VarName,
1966 const char *ElementBuilderName,
Zonr Chang89273bd2010-10-14 20:57:38 +08001967 const char *RenderScriptVar,
1968 unsigned ArraySize) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001969 const char *ElementConstruct = GetBuiltinElementConstruct(ET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001970
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001971 if (ElementConstruct != NULL) {
1972 EB_ADD(ElementConstruct << "(" << RenderScriptVar << ")");
1973 } else {
1974 if ((ET->getClass() == RSExportType::ExportClassPrimitive) ||
Zonr Chang2e1dba62010-10-05 22:20:11 +08001975 (ET->getClass() == RSExportType::ExportClassVector)) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001976 const RSExportPrimitiveType *EPT =
1977 static_cast<const RSExportPrimitiveType*>(ET);
1978 const char *DataKindName = GetElementDataKindName(EPT->getKind());
1979 const char *DataTypeName = GetElementDataTypeName(EPT->getType());
1980 int Size = (ET->getClass() == RSExportType::ExportClassVector) ?
1981 static_cast<const RSExportVectorType*>(ET)->getNumElement() :
1982 1;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001983
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001984 switch (EPT->getKind()) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001985 case RSExportPrimitiveType::DataKindPixelL:
1986 case RSExportPrimitiveType::DataKindPixelA:
1987 case RSExportPrimitiveType::DataKindPixelLA:
1988 case RSExportPrimitiveType::DataKindPixelRGB:
1989 case RSExportPrimitiveType::DataKindPixelRGBA: {
1990 // Element.createPixel()
Zonr Chang89273bd2010-10-14 20:57:38 +08001991 EB_ADD("Element.createPixel(" << RenderScriptVar << ", "
1992 << DataTypeName << ", "
1993 << DataKindName << ")");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001994 break;
1995 }
1996 case RSExportPrimitiveType::DataKindUser:
1997 default: {
Zonr Chang2e1dba62010-10-05 22:20:11 +08001998 if (EPT->getClass() == RSExportType::ExportClassPrimitive) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001999 // Element.createUser()
Zonr Chang89273bd2010-10-14 20:57:38 +08002000 EB_ADD("Element.createUser(" << RenderScriptVar << ", "
2001 << DataTypeName << ")");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002002 } else {
Stephen Hines6e6578a2011-02-07 18:05:48 -08002003 slangAssert((ET->getClass() == RSExportType::ExportClassVector) &&
2004 "Unexpected type.");
Zonr Chang89273bd2010-10-14 20:57:38 +08002005 EB_ADD("Element.createVector(" << RenderScriptVar << ", "
2006 << DataTypeName << ", "
2007 << Size << ")");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002008 }
2009 break;
2010 }
Shih-wei Liaobd49c8f2010-06-17 09:51:36 -07002011 }
Zonr Chang92b344a2010-10-05 20:39:03 +08002012#ifndef NDEBUG
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002013 } else if (ET->getClass() == RSExportType::ExportClassPointer) {
2014 // Pointer type variable should be resolved in
2015 // GetBuiltinElementConstruct()
Stephen Hines6e6578a2011-02-07 18:05:48 -08002016 slangAssert(false && "??");
Zonr Chang92b344a2010-10-05 20:39:03 +08002017 } else if (ET->getClass() == RSExportType::ExportClassMatrix) {
2018 // Matrix type variable should be resolved
2019 // in GetBuiltinElementConstruct()
Stephen Hines6e6578a2011-02-07 18:05:48 -08002020 slangAssert(false && "??");
Zonr Chang92b344a2010-10-05 20:39:03 +08002021#endif
Zonr Chang2e1dba62010-10-05 22:20:11 +08002022 } else if (ET->getClass() == RSExportType::ExportClassConstantArray) {
2023 const RSExportConstantArrayType *ECAT =
2024 static_cast<const RSExportConstantArrayType *>(ET);
Zonr Chang2e1dba62010-10-05 22:20:11 +08002025
Zonr Chang89273bd2010-10-14 20:57:38 +08002026 const RSExportType *ElementType = ECAT->getElementType();
2027 if (ElementType->getClass() != RSExportType::ExportClassRecord) {
2028 genAddElementToElementBuilder(C,
2029 ECAT->getElementType(),
2030 VarName,
2031 ElementBuilderName,
2032 RenderScriptVar,
2033 ECAT->getSize());
2034 } else {
2035 std::string NewElementBuilderName(ElementBuilderName);
2036 NewElementBuilderName.append(1, '_');
Zonr Chang2e1dba62010-10-05 22:20:11 +08002037
Zonr Chang89273bd2010-10-14 20:57:38 +08002038 genBuildElement(C,
2039 NewElementBuilderName.c_str(),
2040 static_cast<const RSExportRecordType*>(ElementType),
2041 RenderScriptVar,
2042 /* IsInline = */true);
2043 ArraySize = ECAT->getSize();
2044 EB_ADD(NewElementBuilderName << ".create()");
2045 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002046 } else if (ET->getClass() == RSExportType::ExportClassRecord) {
2047 // Simalar to case of RSExportType::ExportClassRecord in genPackVarOfType.
2048 //
zonr6315f762010-10-05 15:35:14 +08002049 // TODO(zonr): Generalize these two function such that there's no
2050 // duplicated codes.
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002051 const RSExportRecordType *ERT =
2052 static_cast<const RSExportRecordType*>(ET);
2053 int Pos = 0; // relative pos from now on
2054
2055 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
2056 E = ERT->fields_end();
2057 I != E;
2058 I++) {
2059 const RSExportRecordType::Field *F = *I;
2060 std::string FieldName;
2061 int FieldOffset = F->getOffsetInParent();
2062 int FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
2063 int FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType());
2064
2065 if (!VarName.empty())
2066 FieldName = VarName + "." + F->getName();
2067 else
2068 FieldName = F->getName();
2069
2070 // Alignment
2071 genAddPaddingToElementBuiler(C,
2072 (FieldOffset - Pos),
2073 ElementBuilderName,
2074 RenderScriptVar);
2075
2076 // eb.add(...)
2077 C.addFieldIndexMapping(F);
Zonr Chang89273bd2010-10-14 20:57:38 +08002078 if (F->getType()->getClass() != RSExportType::ExportClassRecord) {
2079 genAddElementToElementBuilder(C,
2080 F->getType(),
2081 FieldName,
2082 ElementBuilderName,
2083 RenderScriptVar,
2084 0);
2085 } else {
2086 std::string NewElementBuilderName(ElementBuilderName);
2087 NewElementBuilderName.append(1, '_');
2088
2089 genBuildElement(C,
2090 NewElementBuilderName.c_str(),
2091 static_cast<const RSExportRecordType*>(F->getType()),
2092 RenderScriptVar,
2093 /* IsInline = */true);
2094
2095 const std::string &VarName = FieldName; // Hack for EB_ADD macro
2096 EB_ADD(NewElementBuilderName << ".create()");
2097 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002098
2099 // There is padding within the field type
2100 genAddPaddingToElementBuiler(C,
2101 (FieldAllocSize - FieldStoreSize),
2102 ElementBuilderName,
2103 RenderScriptVar);
2104
2105 Pos = FieldOffset + FieldAllocSize;
2106 }
2107
2108 // There maybe some padding after the struct
Stephen Hines049229b2011-08-04 09:59:23 -07002109 size_t RecordAllocSize = RSExportType::GetTypeAllocSize(ERT);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002110
2111 genAddPaddingToElementBuiler(C,
Stephen Hines049229b2011-08-04 09:59:23 -07002112 RecordAllocSize - Pos,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002113 ElementBuilderName,
2114 RenderScriptVar);
2115 } else {
Stephen Hines6e6578a2011-02-07 18:05:48 -08002116 slangAssert(false && "Unknown class of type");
Shih-wei Liaob1a28e72010-06-16 16:31:32 -07002117 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002118 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002119}
2120
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002121void RSReflection::genAddPaddingToElementBuiler(Context &C,
2122 int PaddingSize,
2123 const char *ElementBuilderName,
zonr6315f762010-10-05 15:35:14 +08002124 const char *RenderScriptVar) {
Zonr Chang89273bd2010-10-14 20:57:38 +08002125 unsigned ArraySize = 0; // Hack the EB_ADD macro
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002126 while (PaddingSize > 0) {
2127 const std::string &VarName = C.createPaddingField();
2128 if (PaddingSize >= 4) {
Zonr Chang89273bd2010-10-14 20:57:38 +08002129 EB_ADD("Element.U32(" << RenderScriptVar << ")");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002130 PaddingSize -= 4;
2131 } else if (PaddingSize >= 2) {
Zonr Chang89273bd2010-10-14 20:57:38 +08002132 EB_ADD("Element.U16(" << RenderScriptVar << ")");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002133 PaddingSize -= 2;
2134 } else if (PaddingSize >= 1) {
Zonr Chang89273bd2010-10-14 20:57:38 +08002135 EB_ADD("Element.U8(" << RenderScriptVar << ")");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002136 PaddingSize -= 1;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002137 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002138 }
2139 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002140}
2141
2142#undef EB_ADD
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002143/******** Methods to create Element in Java of given record type /end ********/
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002144
Shih-wei Liaob81c6a42010-10-10 14:15:00 -07002145bool RSReflection::reflect(const std::string &OutputPathBase,
2146 const std::string &OutputPackageName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002147 const std::string &InputFileName,
2148 const std::string &OutputBCFileName) {
2149 Context *C = NULL;
2150 std::string ResourceId = "";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002151
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002152 if (!GetClassNameFromFileName(OutputBCFileName, ResourceId))
2153 return false;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002154
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002155 if (ResourceId.empty())
2156 ResourceId = "<Resource ID>";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002157
Shih-wei Liaob81c6a42010-10-10 14:15:00 -07002158 if (OutputPackageName.empty() || OutputPackageName == "-")
2159 C = new Context(OutputPathBase, InputFileName, "<Package Name>",
2160 ResourceId, true);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002161 else
Shih-wei Liaob81c6a42010-10-10 14:15:00 -07002162 C = new Context(OutputPathBase, InputFileName, OutputPackageName,
2163 ResourceId, false);
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002164
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002165 if (C != NULL) {
2166 std::string ErrorMsg, ScriptClassName;
2167 // class ScriptC_<ScriptName>
2168 if (!GetClassNameFromFileName(InputFileName, ScriptClassName))
2169 return false;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002170
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002171 if (ScriptClassName.empty())
2172 ScriptClassName = "<Input Script Name>";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002173
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002174 ScriptClassName.insert(0, RS_SCRIPT_CLASS_NAME_PREFIX);
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002175
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002176 if (mRSContext->getLicenseNote() != NULL) {
2177 C->setLicenseNote(*(mRSContext->getLicenseNote()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002178 }
2179
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002180 if (!genScriptClass(*C, ScriptClassName, ErrorMsg)) {
2181 std::cerr << "Failed to generate class " << ScriptClassName << " ("
2182 << ErrorMsg << ")" << std::endl;
2183 return false;
2184 }
2185
Stephen Hines4cc67fc2011-01-31 16:48:57 -08002186 mGeneratedFileNames->push_back(ScriptClassName);
2187
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002188 // class ScriptField_<TypeName>
2189 for (RSContext::const_export_type_iterator TI =
2190 mRSContext->export_types_begin(),
2191 TE = mRSContext->export_types_end();
2192 TI != TE;
2193 TI++) {
2194 const RSExportType *ET = TI->getValue();
2195
2196 if (ET->getClass() == RSExportType::ExportClassRecord) {
2197 const RSExportRecordType *ERT =
2198 static_cast<const RSExportRecordType*>(ET);
2199
2200 if (!ERT->isArtificial() && !genTypeClass(*C, ERT, ErrorMsg)) {
2201 std::cerr << "Failed to generate type class for struct '"
2202 << ERT->getName() << "' (" << ErrorMsg << ")" << std::endl;
2203 return false;
2204 }
2205 }
2206 }
2207 }
2208
2209 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002210}
2211
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002212/************************** RSReflection::Context **************************/
zonr6315f762010-10-05 15:35:14 +08002213const char *const RSReflection::Context::ApacheLicenseNote =
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002214 "/*\n"
Stephen Hinesd09df092011-02-03 16:01:12 -08002215 " * Copyright (C) 2011 The Android Open Source Project\n"
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002216 " *\n"
2217 " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
2218 " * you may not use this file except in compliance with the License.\n"
2219 " * You may obtain a copy of the License at\n"
2220 " *\n"
2221 " * http://www.apache.org/licenses/LICENSE-2.0\n"
2222 " *\n"
2223 " * Unless required by applicable law or agreed to in writing, software\n"
2224 " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
2225 " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or "
2226 "implied.\n"
2227 " * See the License for the specific language governing permissions and\n"
2228 " * limitations under the License.\n"
2229 " */\n"
2230 "\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002231
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002232const char *const RSReflection::Context::Import[] = {
Stephen Hinesb7d12692011-09-02 18:16:19 -07002233 // Renderscript java class
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002234 "android.renderscript.*",
2235 // Import R
2236 "android.content.res.Resources",
2237 // Import for debugging
Stephen Hines6b64b2b2011-02-01 15:52:56 -08002238 // "android.util.Log",
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002239};
2240
Zonr Chang8c6d9b22010-10-07 18:01:19 +08002241bool RSReflection::Context::openClassFile(const std::string &ClassName,
2242 std::string &ErrorMsg) {
2243 if (!mUseStdout) {
2244 mOF.clear();
2245 std::string Path =
Shih-wei Liaob81c6a42010-10-10 14:15:00 -07002246 RSSlangReflectUtils::ComputePackagedPath(mOutputPathBase.c_str(),
Zonr Chang8c6d9b22010-10-07 18:01:19 +08002247 mPackageName.c_str());
2248
2249 if (!SlangUtils::CreateDirectoryWithParents(Path, &ErrorMsg))
2250 return false;
2251
Raphael8d5a2f62011-02-08 00:15:05 -08002252 std::string ClassFile = Path + OS_PATH_SEPARATOR_STR + ClassName + ".java";
Zonr Chang8c6d9b22010-10-07 18:01:19 +08002253
2254 mOF.open(ClassFile.c_str());
2255 if (!mOF.good()) {
2256 ErrorMsg = "failed to open file '" + ClassFile + "' for write";
2257 return false;
2258 }
2259 }
2260 return true;
2261}
2262
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002263const char *RSReflection::Context::AccessModifierStr(AccessModifier AM) {
2264 switch (AM) {
2265 case AM_Public: return "public"; break;
2266 case AM_Protected: return "protected"; break;
2267 case AM_Private: return "private"; break;
Alex Sakhartchouk38eca1a2011-08-25 10:47:52 -07002268 case AM_PublicSynchronized: return "public synchronized"; break;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002269 default: return ""; break;
2270 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002271}
2272
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002273bool RSReflection::Context::startClass(AccessModifier AM,
2274 bool IsStatic,
2275 const std::string &ClassName,
2276 const char *SuperClassName,
2277 std::string &ErrorMsg) {
2278 if (mVerbose)
2279 std::cout << "Generating " << ClassName << ".java ..." << std::endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002280
Zonr Chang8c6d9b22010-10-07 18:01:19 +08002281 // Open file for class
2282 if (!openClassFile(ClassName, ErrorMsg))
2283 return false;
2284
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002285 // License
2286 out() << mLicenseNote;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002287
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002288 // Notice of generated file
2289 out() << "/*" << std::endl;
2290 out() << " * This file is auto-generated. DO NOT MODIFY!" << std::endl;
Stephen Hinesb7d12692011-09-02 18:16:19 -07002291 out() << " * The source Renderscript file: " << mInputRSFile << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002292 out() << " */" << std::endl;
Ying Wang4e348442010-08-18 10:29:12 -07002293
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002294 // Package
2295 if (!mPackageName.empty())
2296 out() << "package " << mPackageName << ";" << std::endl;
2297 out() << std::endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002298
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002299 // Imports
Stephen Hinese639eb52010-11-08 19:27:20 -08002300 for (unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002301 out() << "import " << Import[i] << ";" << std::endl;
2302 out() << std::endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002303
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002304 // All reflected classes should be annotated as hidden, so that they won't
2305 // be exposed in SDK.
2306 out() << "/**" << std::endl;
2307 out() << " * @hide" << std::endl;
2308 out() << " */" << std::endl;
Ying Wang4e348442010-08-18 10:29:12 -07002309
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002310 out() << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class "
2311 << ClassName;
2312 if (SuperClassName != NULL)
2313 out() << " extends " << SuperClassName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002314
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002315 startBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002316
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002317 mClassName = ClassName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002318
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002319 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002320}
2321
2322void RSReflection::Context::endClass() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002323 endBlock();
2324 if (!mUseStdout)
2325 mOF.close();
2326 clear();
2327 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002328}
2329
2330void RSReflection::Context::startBlock(bool ShouldIndent) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002331 if (ShouldIndent)
2332 indent() << "{" << std::endl;
2333 else
2334 out() << " {" << std::endl;
2335 incIndentLevel();
2336 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002337}
2338
2339void RSReflection::Context::endBlock() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002340 decIndentLevel();
2341 indent() << "}" << std::endl << std::endl;
2342 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002343}
2344
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002345void RSReflection::Context::startTypeClass(const std::string &ClassName) {
2346 indent() << "public static class " << ClassName;
2347 startBlock();
2348 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002349}
2350
2351void RSReflection::Context::endTypeClass() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002352 endBlock();
2353 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002354}
2355
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -07002356void RSReflection::Context::startFunction(AccessModifier AM,
2357 bool IsStatic,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002358 const char *ReturnType,
2359 const std::string &FunctionName,
2360 int Argc, ...) {
2361 ArgTy Args;
2362 va_list vl;
2363 va_start(vl, Argc);
2364
zonr6315f762010-10-05 15:35:14 +08002365 for (int i = 0; i < Argc; i++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002366 const char *ArgType = va_arg(vl, const char*);
2367 const char *ArgName = va_arg(vl, const char*);
2368
zonr6315f762010-10-05 15:35:14 +08002369 Args.push_back(std::make_pair(ArgType, ArgName));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002370 }
2371 va_end(vl);
2372
2373 startFunction(AM, IsStatic, ReturnType, FunctionName, Args);
2374
2375 return;
2376}
2377
2378void RSReflection::Context::startFunction(AccessModifier AM,
2379 bool IsStatic,
2380 const char *ReturnType,
2381 const std::string &FunctionName,
zonr6315f762010-10-05 15:35:14 +08002382 const ArgTy &Args) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002383 indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ")
2384 << ((ReturnType) ? ReturnType : "") << " " << FunctionName << "(";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002385
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002386 bool FirstArg = true;
2387 for (ArgTy::const_iterator I = Args.begin(), E = Args.end();
2388 I != E;
2389 I++) {
2390 if (!FirstArg)
2391 out() << ", ";
2392 else
2393 FirstArg = false;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002394
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002395 out() << I->first << " " << I->second;
2396 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002397
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002398 out() << ")";
2399 startBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002400
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002401 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002402}
2403
2404void RSReflection::Context::endFunction() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07002405 endBlock();
2406 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002407}
Stephen Hinese639eb52010-11-08 19:27:20 -08002408
2409} // namespace slang