1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 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 17 #include "shared.rsh" 18 19 // Ensure that we can reflect correct Java code for a struct with 20 // multiple fields of type struct. Java sets the script global 21 // variable "outer", and then calls a verification invokable 22 // "checkOuter()", passing the expected field values as scalar 23 // arguments. 24 25 struct InnerOne { 26 int x; 27 int y; 28 float f; 29 }; 30 31 typedef struct InnerOne s_innerOne; 32 33 struct InnerTwo { 34 int8_t z; 35 struct InnerOne innerOne; 36 }; 37 38 struct Outer { 39 struct InnerOne innerOneA; 40 long l; // to induce padding 41 struct InnerOne innerOneB; 42 struct InnerTwo innerTwo3[3]; 43 struct InnerTwo innerTwo2[2]; 44 struct InnerOne innerOne4[4]; 45 s_innerOne innerOneC; // does a typedef confuse reflection? 46 }; 47 48 struct Outer outer; 49 50 // Fragment of incoming argument list: Fields for struct InnerOne. 51 // Arguments are named argPrefix"_x", argPrefix"_y", argPrefix"_f". 52 #define ARGS_INNERONE_(argPrefix) \ 53 int argPrefix ## _x, int argPrefix ## _y, float argPrefix ## _f 54 55 // Fragment of incoming argument list: Fields for struct InnerOne 56 // within struct Outer. 57 // Arguments are named outerFieldName"_x", outerFieldName"_y", outerFieldName"_f". 58 #define ARGS_INNERONE_SCALAR(outerFieldName) \ 59 ARGS_INNERONE_(outerFieldName) 60 61 // Fragment of incoming argument list: Fields for element of array of 62 // struct InnerOne within struct Outer. 63 // Arguments are named outerFieldName"_"index"_x", outerFieldName"_"index"_y", 64 // and outerFieldName"_"index"_f". 65 #define ARGS_INNERONE_ARRAY(outerFieldName, index) \ 66 ARGS_INNERONE_(outerFieldName ## _ ## index) 67 68 // Fragment of incoming argument list: Fields for element of array of 69 // struct InnerTwo (with nested InnerOne flattened out) within struct Outer. 70 // Arguments are named outerFieldName"_"index"_z", outerFieldName"_"index"_innerOne_x", etc. 71 #define ARGS_INNERTWO_ARRAY(outerFieldName, index) \ 72 int8_t outerFieldName ## _ ## index ## _z, ARGS_INNERONE_(outerFieldName ## _ ## index ## _innerOne) 73 74 // #define TRACE(...) rsDebug(__VA_ARGS__) 75 #define TRACE(...) (void)0 76 77 void checkOuter(ARGS_INNERONE_SCALAR(innerOneA), 78 long l, 79 ARGS_INNERONE_SCALAR(innerOneB), 80 ARGS_INNERTWO_ARRAY(innerTwo3, 0), 81 ARGS_INNERTWO_ARRAY(innerTwo3, 1), 82 ARGS_INNERTWO_ARRAY(innerTwo3, 2), 83 ARGS_INNERTWO_ARRAY(innerTwo2, 0), 84 ARGS_INNERTWO_ARRAY(innerTwo2, 1), 85 ARGS_INNERONE_ARRAY(innerOne4, 0), 86 ARGS_INNERONE_ARRAY(innerOne4, 1), 87 ARGS_INNERONE_ARRAY(innerOne4, 2), 88 ARGS_INNERONE_ARRAY(innerOne4, 3), 89 ARGS_INNERONE_SCALAR(innerOneC)) { 90 bool failed = false; 91 92 // Compare contents of a struct InnerOne instance against incoming argument values. 93 // Compares instanceName".x" to argPrefix"_x", etc. 94 #define CHECK_INNERONE_(instanceName, argPrefix) \ 95 do { \ 96 TRACE(# instanceName, instanceName.x); \ 97 _RS_ASSERT(instanceName.x == argPrefix ## _x); \ 98 TRACE(# instanceName, instanceName.y); \ 99 _RS_ASSERT(instanceName.y == argPrefix ## _y); \ 100 TRACE(# instanceName, instanceName.f); \ 101 _RS_ASSERT(instanceName.f == argPrefix ## _f); \ 102 } while(false) 103 104 // Compare contents of a struct InnerOne instance within global 105 // variable "outer" against incoming argument values. 106 // Compares "outer."outerFieldName".x" to outerFieldName"_x", etc. 107 #define CHECK_INNERONE_SCALAR(outerFieldName) \ 108 CHECK_INNERONE_(outer.outerFieldName, outerFieldName) 109 110 // Compare contents of element of array of struct InnerOne 111 // instance within global variable "outer" against incoming argument values. 112 // Compares "outer"outerFieldName"["index"].x" to outerFieldName"_"index"_x", etc. 113 #define CHECK_INNERONE_ARRAY(outerFieldName, index) \ 114 CHECK_INNERONE_(outer.outerFieldName[index], outerFieldName ## _ ## index) 115 116 // Compare contents of element of array of struct InnerTwo 117 // instance within global variable "outer" against incoming argument values. 118 // Compares "outer."outerFieldName"["index"].z" to outerFieldName"_"index"_z", 119 // "outer."outerFieldName"["index"].innerOne.x" to outerFieldName""index"_innerOne_x", 120 // etc. 121 #define CHECK_INNERTWO_ARRAY(outerFieldName, index) \ 122 do { \ 123 TRACE(# index, outer.outerFieldName[index].z); \ 124 _RS_ASSERT(outer.outerFieldName[index].z == outerFieldName ## _ ## index ## _z); \ 125 CHECK_INNERONE_(outer.outerFieldName[index].innerOne, outerFieldName ## _ ## index ## _innerOne); \ 126 } while (false); 127 128 CHECK_INNERONE_SCALAR(innerOneA); 129 TRACE("l", outer.l); 130 _RS_ASSERT(outer.l == l); 131 CHECK_INNERONE_SCALAR(innerOneB); 132 CHECK_INNERTWO_ARRAY(innerTwo3, 0); 133 CHECK_INNERTWO_ARRAY(innerTwo3, 1); 134 CHECK_INNERTWO_ARRAY(innerTwo3, 2); 135 CHECK_INNERTWO_ARRAY(innerTwo2, 0); 136 CHECK_INNERTWO_ARRAY(innerTwo2, 1); 137 CHECK_INNERONE_ARRAY(innerOne4, 0); 138 CHECK_INNERONE_ARRAY(innerOne4, 1); 139 CHECK_INNERONE_ARRAY(innerOne4, 2); 140 CHECK_INNERONE_ARRAY(innerOne4, 3); 141 CHECK_INNERONE_SCALAR(innerOneC); 142 143 if (failed) { 144 rsSendToClientBlocking(RS_MSG_TEST_FAILED); 145 } 146 else { 147 rsSendToClientBlocking(RS_MSG_TEST_PASSED); 148 } 149 } 150