History log of /frameworks/compile/slang/tests/P_struct_field/ScriptField_InnerTwo.java.expect
Revision Date Author Comments (<<< Hide modified files) (Show modified files >>>)
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_InnerTwo.java.expect