| 78 | } |
| 79 | |
| 80 | bool ArgumentTypeFuzzer::fuzzArgumentTypes(uint32_t maxVariadicArgs) { |
| 81 | const auto& formalArgs = signature_.argumentTypes(); |
| 82 | auto formalArgsCnt = formalArgs.size(); |
| 83 | |
| 84 | if (returnType_) { |
| 85 | exec::ReverseSignatureBinder binder{signature_, returnType_}; |
| 86 | if (!binder.tryBind()) { |
| 87 | return false; |
| 88 | } |
| 89 | bindings_ = binder.bindings(); |
| 90 | } else { |
| 91 | for (const auto& [name, _] : signature_.variables()) { |
| 92 | bindings_.insert({name, nullptr}); |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | determineUnboundedTypeVariables(); |
| 97 | for (auto i = 0; i < formalArgsCnt; i++) { |
| 98 | TypePtr actualArg; |
| 99 | if (formalArgs[i].baseName() == "any") { |
| 100 | actualArg = randType(); |
| 101 | } else { |
| 102 | actualArg = exec::SignatureBinder::tryResolveType( |
| 103 | formalArgs[i], variables(), bindings_); |
| 104 | BOLT_CHECK(actualArg != nullptr); |
| 105 | } |
| 106 | argumentTypes_.push_back(actualArg); |
| 107 | } |
| 108 | |
| 109 | // Generate random repeats of the last argument type if the signature is |
| 110 | // variadic. |
| 111 | if (signature_.variableArity()) { |
| 112 | auto repeat = boost::random::uniform_int_distribution<uint32_t>( |
| 113 | 0, maxVariadicArgs)(rng_); |
| 114 | auto last = argumentTypes_[formalArgsCnt - 1]; |
| 115 | for (int i = 0; i < repeat; ++i) { |
| 116 | argumentTypes_.push_back(last); |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | return true; |
| 121 | } |
| 122 | |
| 123 | TypePtr ArgumentTypeFuzzer::fuzzReturnType() { |
| 124 | BOLT_CHECK_EQ( |