| 191 | bool skip_next; // FIXME: an ugly hack to skip the next task |
| 192 | |
| 193 | void finalize() { |
| 194 | // aggregate the contraints, map each input byte to a constraint to |
| 195 | // an index in the "global" input array (i.e., the scratch_args) |
| 196 | std::unordered_map<uint32_t, uint32_t> sym_map; |
| 197 | uint32_t gidx = 0; |
| 198 | size_t num_const = constraints_.size(); |
| 199 | for (size_t i = 0; i < num_const; i++) { |
| 200 | auto const& constraint = constraints_[i]; |
| 201 | std::unique_ptr<ConsMeta> cm = std::make_unique<ConsMeta>(); |
| 202 | cm->input_args = constraint->input_args; |
| 203 | cm->comparison = comparisons_[i]; |
| 204 | uint32_t last_offset = -1; |
| 205 | uint32_t size = 0; |
| 206 | for (const auto& [offset, lidx] : constraint->local_map) { |
| 207 | auto gitr = sym_map.find(offset); |
| 208 | if (gitr == sym_map.end()) { |
| 209 | gidx = inputs_.size(); |
| 210 | sym_map[offset] = gidx; |
| 211 | inputs_.push_back(std::make_pair(offset, constraint->inputs.at(offset))); |
| 212 | shapes_[offset] = constraint->shapes.at(offset); |
| 213 | } else { |
| 214 | gidx = gitr->second; |
| 215 | } |
| 216 | // record input to constraint mapping |
| 217 | // skip memcmp constraints |
| 218 | if (cm->comparison != rgd::Memcmp && cm->comparison != rgd::MemcmpN) { |
| 219 | auto slot = cmap_.find(gidx); |
| 220 | if (slot != cmap_.end()) { |
| 221 | slot->second.push_back(i); |
| 222 | } else { |
| 223 | cmap_.emplace(std::make_pair(gidx, std::vector<size_t>{i})); |
| 224 | } |
| 225 | } |
| 226 | // save the mapping between the local index (i.e., where the JIT'ed |
| 227 | // function is going to read the input from) and the global index |
| 228 | // (i.e., where the current value corresponding to the input byte |
| 229 | // is stored in MutInput) |
| 230 | cm->input_args[lidx].second = gidx; |
| 231 | |
| 232 | // check if the input bytes are consecutive |
| 233 | // using std::map ensures that the offsets (keys) are sorted |
| 234 | if (last_offset != -1 && last_offset + 1 != offset) { |
| 235 | // a new set of consecutive input bytes, save the info |
| 236 | // and resset |
| 237 | cm->i2s_candidates.push_back({last_offset + 1 - size, size}); |
| 238 | size = 0; |
| 239 | } |
| 240 | last_offset = offset; |
| 241 | size++; |
| 242 | } |
| 243 | // save the last set of consecutive input bytes |
| 244 | cm->i2s_candidates.push_back({last_offset + 1 - size, size}); |
| 245 | |
| 246 | // process atoi |
| 247 | for (const auto& [offset, info] : constraint->atoi_info) { |
| 248 | // check dependencies |
| 249 | uint32_t length = std::get<2>(info); |
| 250 | for (auto j = 0; j < length; ++j) { |
no test coverage detected