| 1137 | } |
| 1138 | |
| 1139 | Prog* Compiler::Finish(Regexp* re) { |
| 1140 | if (failed_) |
| 1141 | return NULL; |
| 1142 | |
| 1143 | if (prog_->start() == 0 && prog_->start_unanchored() == 0) { |
| 1144 | // No possible matches; keep Fail instruction only. |
| 1145 | ninst_ = 1; |
| 1146 | } |
| 1147 | |
| 1148 | // Hand off the array to Prog. |
| 1149 | prog_->inst_ = std::move(inst_); |
| 1150 | prog_->size_ = ninst_; |
| 1151 | |
| 1152 | prog_->Optimize(); |
| 1153 | prog_->Flatten(); |
| 1154 | prog_->ComputeByteMap(); |
| 1155 | |
| 1156 | if (!prog_->reversed()) { |
| 1157 | std::string prefix; |
| 1158 | bool prefix_foldcase; |
| 1159 | if (re->RequiredPrefixForAccel(&prefix, &prefix_foldcase) && |
| 1160 | !prefix_foldcase) { |
| 1161 | prog_->prefix_size_ = prefix.size(); |
| 1162 | prog_->prefix_front_ = prefix.front(); |
| 1163 | prog_->prefix_back_ = prefix.back(); |
| 1164 | } |
| 1165 | } |
| 1166 | |
| 1167 | // Record remaining memory for DFA. |
| 1168 | if (max_mem_ <= 0) { |
| 1169 | prog_->set_dfa_mem(1<<20); |
| 1170 | } else { |
| 1171 | int64_t m = max_mem_ - sizeof(Prog); |
| 1172 | m -= prog_->size_*sizeof(Prog::Inst); // account for inst_ |
| 1173 | if (prog_->CanBitState()) |
| 1174 | m -= prog_->size_*sizeof(uint16_t); // account for list_heads_ |
| 1175 | if (m < 0) |
| 1176 | m = 0; |
| 1177 | prog_->set_dfa_mem(m); |
| 1178 | } |
| 1179 | |
| 1180 | Prog* p = prog_; |
| 1181 | prog_ = NULL; |
| 1182 | return p; |
| 1183 | } |
| 1184 | |
| 1185 | // Converts Regexp to Prog. |
| 1186 | Prog* Regexp::CompileToProg(int64_t max_mem) { |
no test coverage detected