f3edb0046f0c1389f1318f8e7d4ea3ab9453d599 |
|
14-Sep-2016 |
David Gross <dgross@google.com> |
Fix Java reflec: Assert or uncompileable code for struct-typed field. If an exported struct has two fields of the same struct type, we were getting an assertion: (mFieldIndexMap.find(F) == mFieldIndexMap.end()) && "Nested structure never occurs in C language." If an exported struct has two fields of different struct types, we were getting reflected Java code that can't be compiled ("Duplicate local variable eb_"). The underlying issue is that when generating Java code to create an Element to represent a struct (generating Java method ScriptField_<struct-tag>.createElement()), we were generating Java code recursively when a field is of type struct (diving down into that struct to generate code to represent its fields), rather than generating code that calls ScriptField_<field-struct-tag>.createElement()). This is now fixed. How do we know that Java class ScriptField_<field-struct-tag> exists? Because when we discover that struct <struct-tag> is an exported type, we call RSExportType::Create(), which calls RSExportRecordType::Create(), which calls the RSExportRecordType constructor, which calls RSExportElement::CreateFromDecl() for each field of struct <struct-tag>, which calls RSExportType::Create() for that field's type (thereby recursing); and the RSExportRecordType constructor is responsible for putting a structure on the list of exported types. Therefore, struct <field-struct-tag> will be on the list of exported types, and so we will generate the Java class ScriptField_<field-struct-tag>. What was the reason for the assertion? We were trying to insert a second instance of a field into mFieldIndexMap. This map is cleared at the end of processing a struct (genTypeClass()), and each field we encounter during the type export process is added to it. genTypeClass() is only called at the top level of the export process (i.e., when iterating over the list of exported types). So when we instantiate the same struct (for a field type) within a containing struct a second time (because of two fields with the same struct type), we try to add its fields a second time to the map (intermixed with the fields of the containing struct, incidentally), and assert. Now that we no longer actually instantiate a field type struct even once while processing the exported containing struct type, we no longer assert. Test: aosp_flounder-eng: slang/tests, RsTest 32bit/64bit, cts -m RenderscriptTest Bug: 19545299 Change-Id: I0f35ae3e34830c5caa3f06b81595ce411e25bcf3
/frameworks/compile/slang/tests/P_struct_field/ScriptField_InnerOne.java.expect
|