Add array initializer to jfuzz' potential output.
Rationale:
Array initializers were previously untested. With
some upcoming work on dexfuzz, it will also be
good to stress the use of new-array opcodes more.
Test: run jfuzz
Change-Id: I18bca1ac07f77a562944dfdc055a7561fd7fa80a
diff --git a/tools/jfuzz/jfuzz.cc b/tools/jfuzz/jfuzz.cc
index 82683f2..4cd2335 100644
--- a/tools/jfuzz/jfuzz.cc
+++ b/tools/jfuzz/jfuzz.cc
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <cmath>
#include <random>
#include <inttypes.h>
@@ -54,7 +55,7 @@
* to preserve the property that a given version of JFuzz yields the same
* fuzzed program for a deterministic random seed.
*/
-const char* VERSION = "1.2";
+const char* VERSION = "1.3";
/*
* Maximum number of array dimensions, together with corresponding maximum size
@@ -698,6 +699,72 @@
return mayFollow;
}
+ // Emit one dimension of an array initializer, where parameter dim >= 1
+ // denotes the number of remaining dimensions that should be emitted.
+ void emitArrayInitDim(int dim) {
+ if (dim == 1) {
+ // Last dimension: set of values.
+ fputs("{ ", out_);
+ for (uint32_t i = 0; i < array_size_; i++) {
+ emitExpression(array_type_);
+ fputs(", ", out_);
+ }
+ fputs("}", out_);
+
+ } else {
+ // Outer dimensions: set of sets.
+ fputs("{\n", out_);
+ indentation_ += 2;
+ emitIndentation();
+
+ for (uint32_t i = 0; i < array_size_; i++) {
+ emitArrayInitDim(dim - 1);
+ if (i != array_size_ - 1) {
+ fputs(",\n", out_);
+ emitIndentation();
+ }
+ }
+
+ fputs(",\n", out_);
+ indentation_ -= 2;
+ emitIndentation();
+ fputs("}", out_);
+ }
+ }
+
+ // Emit an array initializer of the following form.
+ // {
+ // type[]..[] tmp = { .. };
+ // mArray = tmp;
+ // }
+ bool emitArrayInit() {
+ // Avoid elaborate array initializers.
+ uint64_t p = pow(array_size_, array_dim_);
+ if (p > 20) {
+ return emitAssignment(); // fall back
+ }
+
+ fputs("{\n", out_);
+
+ indentation_ += 2;
+ emitIndentation();
+ emitType(array_type_);
+ for (uint32_t i = 0; i < array_dim_; i++) {
+ fputs("[]", out_);
+ }
+ fputs(" tmp = ", out_);
+ emitArrayInitDim(array_dim_);
+ fputs(";\n", out_);
+
+ emitIndentation();
+ fputs("mArray = tmp;\n", out_);
+
+ indentation_ -= 2;
+ emitIndentation();
+ fputs("}\n", out_);
+ return true;
+ }
+
// Emit a for loop.
bool emitForLoop() {
// Continuing loop nest becomes less likely as the depth grows.
@@ -874,10 +941,11 @@
case 2: return emitContinue(); break;
case 3: return emitBreak(); break;
case 4: return emitScope(); break;
- case 5: return emitForLoop(); break;
- case 6: return emitDoLoop(); break;
- case 7: return emitIfStmt(); break;
- case 8: return emitSwitch(); break;
+ case 5: return emitArrayInit(); break;
+ case 6: return emitForLoop(); break;
+ case 7: return emitDoLoop(); break;
+ case 8: return emitIfStmt(); break;
+ case 9: return emitSwitch(); break;
default: return emitAssignment(); break;
}
}